mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2024-12-22 08:54:33 +03:00
commit
5c2e99cba1
8 changed files with 924 additions and 1068 deletions
5
.github/dependabot.yml
vendored
5
.github/dependabot.yml
vendored
|
@ -12,6 +12,11 @@ updates:
|
||||||
fontawesome:
|
fontawesome:
|
||||||
patterns:
|
patterns:
|
||||||
- '@fortawesome/*'
|
- '@fortawesome/*'
|
||||||
|
eslint:
|
||||||
|
patterns:
|
||||||
|
- '@shlinkio/eslint-config-js-coding-standard'
|
||||||
|
- '@typescript-eslint/*'
|
||||||
|
- 'eslint'
|
||||||
shlink:
|
shlink:
|
||||||
patterns:
|
patterns:
|
||||||
- '@shlinkio/*'
|
- '@shlinkio/*'
|
||||||
|
|
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.1.1] - 2024-04-11
|
||||||
|
### Added
|
||||||
|
* [shlink-web-component#293](https://github.com/shlinkio/shlink-web-component/issues/293) Allow ordering redirect rules via drag'n'drop.
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
* Update JS coding standard
|
||||||
|
* [#1132](https://github.com/shlinkio/shlink-web-client/issues/1132) Add warning message in "validate URLs" setting, indicating it is ignored when consuming Shlink >=4.0.0.
|
||||||
|
|
||||||
|
### Deprecated
|
||||||
|
* *Nothing*
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
* *Nothing*
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
* [shlink-web-component#294](https://github.com/shlinkio/shlink-web-component/issues/294) Make sure "validate URL" control is not displayed in short URL creation/edition, when consuming Shlink >=4.0.0.
|
||||||
|
* [#1130](https://github.com/shlinkio/shlink-web-client/issues/1130) Fix importing servers in Firefox for Android when the CSV file contains spaces.
|
||||||
|
* [#1133](https://github.com/shlinkio/shlink-web-client/issues/1133) Fix Shlink versions alignment in server error pages.
|
||||||
|
|
||||||
|
|
||||||
## [4.1.0] - 2024-03-17
|
## [4.1.0] - 2024-03-17
|
||||||
### Added
|
### Added
|
||||||
* [#1079](https://github.com/shlinkio/shlink-web-client/issues/1079) Add support Shlink 4.0.0.
|
* [#1079](https://github.com/shlinkio/shlink-web-client/issues/1079) Add support Shlink 4.0.0.
|
||||||
|
|
1864
package-lock.json
generated
1864
package-lock.json
generated
File diff suppressed because it is too large
Load diff
36
package.json
36
package.json
|
@ -24,24 +24,24 @@
|
||||||
"test:verbose": "npm run test -- --verbose"
|
"test:verbose": "npm run test -- --verbose"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fortawesome/fontawesome-free": "^6.5.1",
|
"@fortawesome/fontawesome-free": "^6.5.2",
|
||||||
"@fortawesome/fontawesome-svg-core": "^6.5.1",
|
"@fortawesome/fontawesome-svg-core": "^6.5.2",
|
||||||
"@fortawesome/free-brands-svg-icons": "^6.5.1",
|
"@fortawesome/free-brands-svg-icons": "^6.5.2",
|
||||||
"@fortawesome/free-regular-svg-icons": "^6.5.1",
|
"@fortawesome/free-regular-svg-icons": "^6.5.2",
|
||||||
"@fortawesome/free-solid-svg-icons": "^6.5.1",
|
"@fortawesome/free-solid-svg-icons": "^6.5.2",
|
||||||
"@fortawesome/react-fontawesome": "^0.2.0",
|
"@fortawesome/react-fontawesome": "^0.2.0",
|
||||||
"@json2csv/plainjs": "^7.0.6",
|
"@json2csv/plainjs": "^7.0.6",
|
||||||
"@reduxjs/toolkit": "^2.2.1",
|
"@reduxjs/toolkit": "^2.2.3",
|
||||||
"@shlinkio/data-manipulation": "^1.0.3",
|
"@shlinkio/data-manipulation": "^1.0.3",
|
||||||
"@shlinkio/shlink-frontend-kit": "^0.5.0",
|
"@shlinkio/shlink-frontend-kit": "^0.5.0",
|
||||||
"@shlinkio/shlink-js-sdk": "^1.0.0",
|
"@shlinkio/shlink-js-sdk": "^1.0.0",
|
||||||
"@shlinkio/shlink-web-component": "^0.6.0",
|
"@shlinkio/shlink-web-component": "^0.6.1",
|
||||||
"bootstrap": "5.2.3",
|
"bootstrap": "5.2.3",
|
||||||
"bottlejs": "^2.0.1",
|
"bottlejs": "^2.0.1",
|
||||||
"clsx": "^2.1.0",
|
"clsx": "^2.1.0",
|
||||||
"compare-versions": "^6.1.0",
|
"compare-versions": "^6.1.0",
|
||||||
"csvtojson": "^2.0.10",
|
"csvtojson": "^2.0.10",
|
||||||
"date-fns": "^3.5.0",
|
"date-fns": "^3.6.0",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-external-link": "^2.2.0",
|
"react-external-link": "^2.2.0",
|
||||||
|
@ -57,28 +57,30 @@
|
||||||
"workbox-strategies": "^7.0.0"
|
"workbox-strategies": "^7.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@shlinkio/eslint-config-js-coding-standard": "~2.3.0",
|
"@shlinkio/eslint-config-js-coding-standard": "~2.4.1",
|
||||||
"@shlinkio/stylelint-config-css-coding-standard": "~1.1.1",
|
"@shlinkio/stylelint-config-css-coding-standard": "~1.1.1",
|
||||||
"@testing-library/jest-dom": "^6.4.2",
|
"@testing-library/jest-dom": "^6.4.2",
|
||||||
"@testing-library/react": "^14.2.1",
|
"@testing-library/react": "^14.2.2",
|
||||||
"@testing-library/user-event": "^14.5.2",
|
"@testing-library/user-event": "^14.5.2",
|
||||||
"@total-typescript/shoehorn": "^0.1.2",
|
"@total-typescript/shoehorn": "^0.1.2",
|
||||||
"@types/react": "^18.2.66",
|
"@types/react": "^18.2.74",
|
||||||
"@types/react-dom": "^18.2.22",
|
"@types/react-dom": "^18.2.24",
|
||||||
"@types/uuid": "^9.0.8",
|
"@types/uuid": "^9.0.8",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^7.5.0",
|
||||||
|
"@typescript-eslint/parser": "^7.5.0",
|
||||||
"@vitejs/plugin-react": "^4.2.1",
|
"@vitejs/plugin-react": "^4.2.1",
|
||||||
"@vitest/coverage-v8": "^1.4.0",
|
"@vitest/coverage-v8": "^1.4.0",
|
||||||
"adm-zip": "^0.5.12",
|
"adm-zip": "^0.5.12",
|
||||||
"axe-core": "^4.8.4",
|
"axe-core": "^4.9.0",
|
||||||
"chalk": "^5.3.0",
|
"chalk": "^5.3.0",
|
||||||
"eslint": "^8.57.0",
|
"eslint": "^8.57.0",
|
||||||
"history": "^5.3.0",
|
"history": "^5.3.0",
|
||||||
"jsdom": "^24.0.0",
|
"jsdom": "^24.0.0",
|
||||||
"sass": "^1.72.0",
|
"sass": "^1.74.1",
|
||||||
"stylelint": "^15.11.0",
|
"stylelint": "^15.11.0",
|
||||||
"typescript": "^5.4.2",
|
"typescript": "^5.4.4",
|
||||||
"vite": "^5.1.6",
|
"vite": "^5.2.8",
|
||||||
"vite-plugin-pwa": "^0.19.4",
|
"vite-plugin-pwa": "^0.19.8",
|
||||||
"vitest": "^1.2.2"
|
"vitest": "^1.2.2"
|
||||||
},
|
},
|
||||||
"browserslist": [
|
"browserslist": [
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import { clsx } from 'clsx';
|
import { clsx } from 'clsx';
|
||||||
import { useMemo } from 'react';
|
|
||||||
import { useLocation } from 'react-router-dom';
|
|
||||||
import type { SelectedServer } from '../servers/data';
|
import type { SelectedServer } from '../servers/data';
|
||||||
|
import { isReachableServer } from '../servers/data';
|
||||||
import { ShlinkVersions } from './ShlinkVersions';
|
import { ShlinkVersions } from './ShlinkVersions';
|
||||||
import './ShlinkVersionsContainer.scss';
|
import './ShlinkVersionsContainer.scss';
|
||||||
|
|
||||||
|
@ -9,19 +8,12 @@ export type ShlinkVersionsContainerProps = {
|
||||||
selectedServer: SelectedServer;
|
selectedServer: SelectedServer;
|
||||||
};
|
};
|
||||||
|
|
||||||
const SHLINK_CONTAINER_PATH_PATTERN = /^\/server\/[a-zA-Z0-9-]*\/(?!edit)/;
|
export const ShlinkVersionsContainer = ({ selectedServer }: ShlinkVersionsContainerProps) => (
|
||||||
|
<div
|
||||||
export const ShlinkVersionsContainer = ({ selectedServer }: ShlinkVersionsContainerProps) => {
|
className={clsx('text-center', {
|
||||||
const { pathname } = useLocation();
|
'shlink-versions-container--with-sidebar': isReachableServer(selectedServer),
|
||||||
const withPadding = useMemo(() => SHLINK_CONTAINER_PATH_PATTERN.test(pathname), [pathname]);
|
})}
|
||||||
|
>
|
||||||
const classes = clsx('text-center', {
|
<ShlinkVersions selectedServer={selectedServer} />
|
||||||
'shlink-versions-container--with-sidebar': withPadding,
|
</div>
|
||||||
});
|
);
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={classes}>
|
|
||||||
<ShlinkVersions selectedServer={selectedServer} />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
|
@ -87,7 +87,7 @@ const ImportServersBtn: FCWithDeps<ImportServersBtnConnectProps, ImportServersBt
|
||||||
You can create servers by importing a CSV file with <b>name</b>, <b>apiKey</b> and <b>url</b> columns.
|
You can create servers by importing a CSV file with <b>name</b>, <b>apiKey</b> and <b>url</b> columns.
|
||||||
</UncontrolledTooltip>
|
</UncontrolledTooltip>
|
||||||
|
|
||||||
<input type="file" accept="text/csv" className="d-none" ref={ref} onChange={onFile} aria-hidden />
|
<input type="file" accept=".csv" className="d-none" ref={ref} onChange={onFile} aria-hidden />
|
||||||
|
|
||||||
<DuplicatedServersModal
|
<DuplicatedServersModal
|
||||||
isOpen={isModalOpen}
|
isOpen={isModalOpen}
|
||||||
|
|
|
@ -33,7 +33,8 @@ export const ShortUrlCreationSettings: FC<ShortUrlCreationProps> = ({ settings,
|
||||||
checked={shortUrlCreation.validateUrls ?? false}
|
checked={shortUrlCreation.validateUrls ?? false}
|
||||||
onChange={(validateUrls) => setShortUrlCreationSettings({ ...shortUrlCreation, validateUrls })}
|
onChange={(validateUrls) => setShortUrlCreationSettings({ ...shortUrlCreation, validateUrls })}
|
||||||
>
|
>
|
||||||
Request validation on long URLs when creating new short URLs.
|
Request validation on long URLs when creating new short URLs.{' '}
|
||||||
|
<b>This option is ignored by Shlink {'>='}4.0.0</b>
|
||||||
<FormText>
|
<FormText>
|
||||||
The initial state of the <b>Validate URL</b> checkbox will
|
The initial state of the <b>Validate URL</b> checkbox will
|
||||||
be <b>{shortUrlCreation.validateUrls ? 'checked' : 'unchecked'}</b>.
|
be <b>{shortUrlCreation.validateUrls ? 'checked' : 'unchecked'}</b>.
|
||||||
|
|
|
@ -1,30 +1,26 @@
|
||||||
import { render } from '@testing-library/react';
|
import { render } from '@testing-library/react';
|
||||||
import { fromPartial } from '@total-typescript/shoehorn';
|
import { fromPartial } from '@total-typescript/shoehorn';
|
||||||
import { createMemoryHistory } from 'history';
|
|
||||||
import { Router } from 'react-router-dom';
|
|
||||||
import { ShlinkVersionsContainer } from '../../src/common/ShlinkVersionsContainer';
|
import { ShlinkVersionsContainer } from '../../src/common/ShlinkVersionsContainer';
|
||||||
|
import type { ReachableServer, SelectedServer } from '../../src/servers/data';
|
||||||
import { checkAccessibility } from '../__helpers__/accessibility';
|
import { checkAccessibility } from '../__helpers__/accessibility';
|
||||||
|
|
||||||
describe('<ShlinkVersionsContainer />', () => {
|
describe('<ShlinkVersionsContainer />', () => {
|
||||||
const setUp = (activeRoute: string = '') => {
|
const setUp = (selectedServer: SelectedServer = null) => render(
|
||||||
const history = createMemoryHistory();
|
<ShlinkVersionsContainer selectedServer={selectedServer} />,
|
||||||
history.push(activeRoute);
|
);
|
||||||
|
|
||||||
return render(
|
|
||||||
<Router location={history.location} navigator={history}>
|
|
||||||
<ShlinkVersionsContainer selectedServer={fromPartial({})} />
|
|
||||||
</Router>,
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
it('passes a11y checks', () => checkAccessibility(setUp()));
|
|
||||||
|
|
||||||
it.each([
|
it.each([
|
||||||
['/something', 'text-center'],
|
[null],
|
||||||
['/server/foo/edit', 'text-center'],
|
[fromPartial<SelectedServer>({})],
|
||||||
['/server/foo/bar', 'text-center shlink-versions-container--with-sidebar'],
|
[fromPartial<ReachableServer>({ version: '1.0.0', printableVersion: 'v1.0.0' })],
|
||||||
])('renders proper col classes based on sidebar status', (sidebar, expectedClasses) => {
|
])('passes a11y checks', (selectedServer) => checkAccessibility(setUp(selectedServer)));
|
||||||
const { container } = setUp(sidebar);
|
|
||||||
|
it.each([
|
||||||
|
[null, 'text-center'],
|
||||||
|
[fromPartial<SelectedServer>({}), 'text-center'],
|
||||||
|
[fromPartial<ReachableServer>({ version: '1.0.0' }), 'text-center shlink-versions-container--with-sidebar'],
|
||||||
|
])('renders proper col classes based on sidebar status', (selectedServer, expectedClasses) => {
|
||||||
|
const { container } = setUp(selectedServer);
|
||||||
expect(container.firstChild).toHaveAttribute('class', `${expectedClasses}`);
|
expect(container.firstChild).toHaveAttribute('class', `${expectedClasses}`);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue