From a3d6944fc199ef4a83ee1315c4373516618dfa1f Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Fri, 7 Jan 2022 16:16:53 +0100 Subject: [PATCH 1/6] Added Twitter follow badge to readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index be8dc30e..2d431d2a 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ [![GitHub release](https://img.shields.io/github/release/shlinkio/shlink-web-client.svg?style=flat-square)](https://github.com/shlinkio/shlink-web-client/releases/latest) [![Docker pulls](https://img.shields.io/docker/pulls/shlinkio/shlink-web-client.svg?logo=docker&style=flat-square)](https://hub.docker.com/r/shlinkio/shlink-web-client/) [![GitHub license](https://img.shields.io/github/license/shlinkio/shlink-web-client.svg?style=flat-square)](https://github.com/shlinkio/shlink-web-client/blob/main/LICENSE) +[![Twitter](https://img.shields.io/twitter/follow/shlinkio?color=blue&label=follow&logo=twitter&style=flat-square)](https://twitter.com/shlinkio) [![Paypal Donate](https://img.shields.io/badge/Donate-paypal-blue.svg?style=flat-square&logo=paypal&colorA=cccccc)](https://slnk.to/donate) A ReactJS-based progressive web application for [Shlink](https://shlink.io). From 2ad2d69b2b1415b258f7e11d40ab6d11d4f924da Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Sat, 8 Jan 2022 10:19:20 +0100 Subject: [PATCH 2/6] Fixed Shlink logo not being vertically aligned in welcome screen --- src/common/Home.scss | 8 ++++++++ src/common/Home.tsx | 6 ++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/common/Home.scss b/src/common/Home.scss index e3bf4a88..91c7f381 100644 --- a/src/common/Home.scss +++ b/src/common/Home.scss @@ -12,8 +12,16 @@ } } +.home__logo-wrapper { + padding: 1.5rem !important; + height: 100% !important; + min-height: 300px; +} + .home__logo { @include vertical-align(); + + width: calc(100% - 3rem); } .home__main-card { diff --git a/src/common/Home.tsx b/src/common/Home.tsx index 873de19e..4b53b8b8 100644 --- a/src/common/Home.tsx +++ b/src/common/Home.tsx @@ -30,8 +30,10 @@ const Home = ({ servers, history }: HomeProps) => {
-
- +
+
+ +
From 27476d8b2388da21da3e3071203b2b61c90cb29d Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Sat, 8 Jan 2022 10:22:51 +0100 Subject: [PATCH 3/6] Added missing border in welcome screen title --- src/common/Home.scss | 5 +++++ src/common/Home.tsx | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/common/Home.scss b/src/common/Home.scss index 91c7f381..3badce49 100644 --- a/src/common/Home.scss +++ b/src/common/Home.scss @@ -33,6 +33,11 @@ } } +.home__title-wrapper { + padding: 1.5rem !important; + border-bottom: 1px solid var(--border-color); +} + .home__title { text-align: center; font-size: 1.75rem; diff --git a/src/common/Home.tsx b/src/common/Home.tsx index 4b53b8b8..2ca4f42d 100644 --- a/src/common/Home.tsx +++ b/src/common/Home.tsx @@ -37,7 +37,7 @@ const Home = ({ servers, history }: HomeProps) => {
-
+

Welcome!

From 112a8cdf2fcc2173e4ecb36b4aca04939d997dde Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Sat, 8 Jan 2022 10:24:07 +0100 Subject: [PATCH 4/6] Updated changelog --- CHANGELOG.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8684440f..389c946f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,23 @@ 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). +## [Unreleased] +### Added +* *Nothing* + +### Changed +* *Nothing* + +### Deprecated +* *Nothing* + +### Removed +* *Nothing* + +### Fixed +* [#555](https://github.com/shlinkio/shlink-web-client/issues/555) Fixed vertical alignment in welcome screen logo. + + ## [3.5.0] - 2022-01-01 ### Added * [#407](https://github.com/shlinkio/shlink-web-client/pull/407) Improved how visits (short URLs, tags and orphan) are loaded, to avoid ending up in a page with "There are no visits matching current filter". From 2e963bdc8efca3b12cc01d725d562a9d210b357c Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Sat, 8 Jan 2022 10:51:34 +0100 Subject: [PATCH 5/6] Fixed short URLs list in overview page --- CHANGELOG.md | 1 + src/servers/Overview.tsx | 4 +- src/short-urls/reducers/shortUrlsList.ts | 9 ++-- .../short-urls/reducers/shortUrlsList.test.ts | 46 +++++++++++++++---- 4 files changed, 45 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 389c946f..ce8b0a99 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ### Fixed * [#555](https://github.com/shlinkio/shlink-web-client/issues/555) Fixed vertical alignment in welcome screen logo. +* [#554](https://github.com/shlinkio/shlink-web-client/issues/554) Fixed behavior in overview page, where items in the list of short URLs were stripped out when creating new ones, even if the amount of short URLs was still not yet big enough. ## [3.5.0] - 2022-01-01 diff --git a/src/servers/Overview.tsx b/src/servers/Overview.tsx index a68d3e17..64b9061d 100644 --- a/src/servers/Overview.tsx +++ b/src/servers/Overview.tsx @@ -1,7 +1,7 @@ import { FC, useEffect } from 'react'; import { Card, CardBody, CardHeader, CardText, CardTitle, Row } from 'reactstrap'; import { Link, useHistory } from 'react-router-dom'; -import { ShortUrlsList as ShortUrlsListState } from '../short-urls/reducers/shortUrlsList'; +import { ITEMS_IN_OVERVIEW_PAGE, ShortUrlsList as ShortUrlsListState } from '../short-urls/reducers/shortUrlsList'; import { prettify } from '../utils/helpers/numbers'; import { TagsList } from '../tags/reducers/tagsList'; import { ShortUrlsTableProps } from '../short-urls/ShortUrlsTable'; @@ -44,7 +44,7 @@ export const Overview = ( const history = useHistory(); useEffect(() => { - listShortUrls({ itemsPerPage: 5, orderBy: { field: 'dateCreated', dir: 'DESC' } }); + listShortUrls({ itemsPerPage: ITEMS_IN_OVERVIEW_PAGE, orderBy: { field: 'dateCreated', dir: 'DESC' } }); listTags(); loadVisitsOverview(); }, []); diff --git a/src/short-urls/reducers/shortUrlsList.ts b/src/short-urls/reducers/shortUrlsList.ts index 894975ac..c1f272da 100644 --- a/src/short-urls/reducers/shortUrlsList.ts +++ b/src/short-urls/reducers/shortUrlsList.ts @@ -1,4 +1,4 @@ -import { assoc, assocPath, init, last, pipe, reject } from 'ramda'; +import { assoc, assocPath, last, pipe, reject } from 'ramda'; import { Action, Dispatch } from 'redux'; import { shortUrlMatches } from '../helpers'; import { CREATE_VISITS, CreateVisitsAction } from '../../visits/reducers/visitCreation'; @@ -16,6 +16,8 @@ export const LIST_SHORT_URLS_ERROR = 'shlink/shortUrlsList/LIST_SHORT_URLS_ERROR export const LIST_SHORT_URLS = 'shlink/shortUrlsList/LIST_SHORT_URLS'; /* eslint-enable padding-line-between-statements */ +export const ITEMS_IN_OVERVIEW_PAGE = 5; + export interface ShortUrlsList { shortUrls?: ShlinkShortUrlsResponse; loading: boolean; @@ -75,10 +77,11 @@ export default buildReducer({ ), [CREATE_SHORT_URL]: pipe( // The only place where the list and the creation form coexist is the overview page. - // There we can assume we are displaying page 1, and therefore, we can safely prepend the new short URL and remove the last one. + // There we can assume we are displaying page 1, and therefore, we can safely prepend the new short URL. + // We can also remove the items above the amount that is displayed there. (state: ShortUrlsList, { result }: CreateShortUrlAction) => !state.shortUrls ? state : assocPath( [ 'shortUrls', 'data' ], - [ result, ...init(state.shortUrls.data) ], + [ result, ...state.shortUrls.data.slice(0, ITEMS_IN_OVERVIEW_PAGE - 1) ], state, ), (state: ShortUrlsList) => !state.shortUrls ? state : assocPath( diff --git a/test/short-urls/reducers/shortUrlsList.test.ts b/test/short-urls/reducers/shortUrlsList.test.ts index 031f6a23..8eac84c3 100644 --- a/test/short-urls/reducers/shortUrlsList.test.ts +++ b/test/short-urls/reducers/shortUrlsList.test.ts @@ -14,6 +14,8 @@ import { CREATE_SHORT_URL } from '../../../src/short-urls/reducers/shortUrlCreat import { SHORT_URL_EDITED } from '../../../src/short-urls/reducers/shortUrlEdition'; describe('shortUrlsListReducer', () => { + const shortCode = 'abc123'; + describe('reducer', () => { it('returns loading on LIST_SHORT_URLS_START', () => expect(reducer(undefined, { type: LIST_SHORT_URLS_START } as any)).toEqual({ @@ -35,7 +37,6 @@ describe('shortUrlsListReducer', () => { })); it('removes matching URL and reduces total on SHORT_URL_DELETED', () => { - const shortCode = 'abc123'; const state = { shortUrls: Mock.of({ data: [ @@ -72,7 +73,6 @@ describe('shortUrlsListReducer', () => { [[{}], 10 ], [[], 10 ], ])('updates visits count on CREATE_VISITS', (createdVisits, expectedCount) => { - const shortCode = 'abc123'; const state = { shortUrls: Mock.of({ data: [ @@ -98,16 +98,42 @@ describe('shortUrlsListReducer', () => { }); }); - it('prepends new short URL and increases total on CREATE_SHORT_URL', () => { + it.each([ + [ + [ + Mock.of({ shortCode }), + Mock.of({ shortCode, domain: 'example.com' }), + Mock.of({ shortCode: 'foo' }), + ], + [{ shortCode: 'newOne' }, { shortCode }, { shortCode, domain: 'example.com' }, { shortCode: 'foo' }], + ], + [ + [ + Mock.of({ shortCode }), + Mock.of({ shortCode: 'code' }), + Mock.of({ shortCode: 'foo' }), + Mock.of({ shortCode: 'bar' }), + Mock.of({ shortCode: 'baz' }), + ], + [{ shortCode: 'newOne' }, { shortCode }, { shortCode: 'code' }, { shortCode: 'foo' }, { shortCode: 'bar' }], + ], + [ + [ + Mock.of({ shortCode }), + Mock.of({ shortCode: 'code' }), + Mock.of({ shortCode: 'foo' }), + Mock.of({ shortCode: 'bar' }), + Mock.of({ shortCode: 'baz1' }), + Mock.of({ shortCode: 'baz2' }), + Mock.of({ shortCode: 'baz3' }), + ], + [{ shortCode: 'newOne' }, { shortCode }, { shortCode: 'code' }, { shortCode: 'foo' }, { shortCode: 'bar' }], + ], + ])('prepends new short URL and increases total on CREATE_SHORT_URL', (data, expectedData) => { const newShortUrl = Mock.of({ shortCode: 'newOne' }); - const shortCode = 'abc123'; const state = { shortUrls: Mock.of({ - data: [ - Mock.of({ shortCode }), - Mock.of({ shortCode, domain: 'example.com' }), - Mock.of({ shortCode: 'foo' }), - ], + data, pagination: Mock.of({ totalItems: 15, }), @@ -118,7 +144,7 @@ describe('shortUrlsListReducer', () => { expect(reducer(state, { type: CREATE_SHORT_URL, result: newShortUrl } as any)).toEqual({ shortUrls: { - data: [{ shortCode: 'newOne' }, { shortCode }, { shortCode, domain: 'example.com' }], + data: expectedData, pagination: { totalItems: 16 }, }, loading: false, From 715128a65303084d5073fa8aabf22226d1e9cb81 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Sat, 8 Jan 2022 11:14:11 +0100 Subject: [PATCH 6/6] Fixed new tags added to new short URLs, not appearing on tags autosuggest --- CHANGELOG.md | 3 ++- src/tags/reducers/tagsList.ts | 6 ++++++ test/tags/reducers/tagsList.test.ts | 15 +++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ce8b0a99..f389d803 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ 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). -## [Unreleased] +## [3.5.1] - 2022-01-08 ### Added * *Nothing* @@ -20,6 +20,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ### Fixed * [#555](https://github.com/shlinkio/shlink-web-client/issues/555) Fixed vertical alignment in welcome screen logo. * [#554](https://github.com/shlinkio/shlink-web-client/issues/554) Fixed behavior in overview page, where items in the list of short URLs were stripped out when creating new ones, even if the amount of short URLs was still not yet big enough. +* [#557](https://github.com/shlinkio/shlink-web-client/issues/557) Fixed new tags added to new short URLs, not appearing on tags autosuggest. ## [3.5.0] - 2022-01-01 diff --git a/src/tags/reducers/tagsList.ts b/src/tags/reducers/tagsList.ts index 5859f818..fafbd339 100644 --- a/src/tags/reducers/tagsList.ts +++ b/src/tags/reducers/tagsList.ts @@ -9,6 +9,7 @@ import { CreateVisit, Stats } from '../../visits/types'; import { parseApiError } from '../../api/utils'; import { TagStats } from '../data'; import { ApiErrorAction } from '../../api/types/actions'; +import { CREATE_SHORT_URL, CreateShortUrlAction } from '../../short-urls/reducers/shortUrlCreation'; import { DeleteTagAction, TAG_DELETED } from './tagDelete'; import { EditTagAction, TAG_EDITED } from './tagEdit'; @@ -42,6 +43,7 @@ interface FilterTagsAction extends Action { type TagsCombinedAction = ListTagsAction & DeleteTagAction & CreateVisitsAction +& CreateShortUrlAction & EditTagAction & FilterTagsAction & ApiErrorAction; @@ -102,6 +104,10 @@ export default buildReducer({ ...state, stats: increaseVisitsForTags(calculateVisitsPerTag(createdVisits), state.stats), }), + [CREATE_SHORT_URL]: ({ tags: stateTags, ...rest }, { result }) => ({ + ...rest, + tags: stateTags.concat(result.tags.filter((tag) => !stateTags.includes(tag))), // More performant than [ ...new Set(...) ] + }), }, initialState); export const listTags = (buildShlinkApiClient: ShlinkApiClientBuilder, force = true) => () => async ( diff --git a/test/tags/reducers/tagsList.test.ts b/test/tags/reducers/tagsList.test.ts index 884efc1b..67bf868f 100644 --- a/test/tags/reducers/tagsList.test.ts +++ b/test/tags/reducers/tagsList.test.ts @@ -11,6 +11,8 @@ import reducer, { import { TAG_DELETED } from '../../../src/tags/reducers/tagDelete'; import { TAG_EDITED } from '../../../src/tags/reducers/tagEdit'; import { ShlinkState } from '../../../src/container/types'; +import { ShortUrl } from '../../../src/short-urls/data'; +import { CREATE_SHORT_URL } from '../../../src/short-urls/reducers/shortUrlCreation'; describe('tagsListReducer', () => { const state = (props: Partial) => Mock.of(props); @@ -74,6 +76,19 @@ describe('tagsListReducer', () => { filteredTags, }); }); + + it.each([ + [[ 'foo', 'foo3', 'bar3', 'fo' ], [ 'foo', 'bar', 'baz', 'foo2', 'fo', 'foo3', 'bar3' ]], + [[ 'foo', 'bar' ], [ 'foo', 'bar', 'baz', 'foo2', 'fo' ]], + [[ 'new', 'tag' ], [ 'foo', 'bar', 'baz', 'foo2', 'fo', 'new', 'tag' ]], + ])('appends new short URL\'s tags to the list of tags on CREATE_SHORT_URL', (shortUrlTags, expectedTags) => { + const tags = [ 'foo', 'bar', 'baz', 'foo2', 'fo' ]; + const result = Mock.of({ tags: shortUrlTags }); + + expect(reducer(state({ tags }), { type: CREATE_SHORT_URL, result } as any)).toEqual({ + tags: expectedTags, + }); + }); }); describe('filterTags', () => {