From 7fd360495ba18861ef449cb74e302137ff962057 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Sat, 12 Mar 2022 20:51:30 +0100 Subject: [PATCH] Created button to use when anything needs to be exported --- src/settings/ShortUrlsListSettings.tsx | 4 +-- src/short-urls/ShortUrlsFilteringBar.tsx | 40 +++++++++++++--------- src/short-urls/ShortUrlsList.tsx | 13 ++++--- src/short-urls/services/provideServices.ts | 1 - src/utils/ExportBtn.tsx | 17 +++++++++ src/visits/VisitsStats.tsx | 12 +++---- test/visits/VisitsStats.test.tsx | 5 +-- 7 files changed, 57 insertions(+), 35 deletions(-) create mode 100644 src/utils/ExportBtn.tsx diff --git a/src/settings/ShortUrlsListSettings.tsx b/src/settings/ShortUrlsListSettings.tsx index d38622cc..bb5f6f8c 100644 --- a/src/settings/ShortUrlsListSettings.tsx +++ b/src/settings/ShortUrlsListSettings.tsx @@ -5,12 +5,12 @@ import { SimpleCard } from '../utils/SimpleCard'; import { LabeledFormGroup } from '../utils/forms/LabeledFormGroup'; import { DEFAULT_SHORT_URLS_ORDERING, Settings, ShortUrlsListSettings as ShortUrlsSettings } from './reducers/settings'; -interface ShortUrlsListProps { +interface ShortUrlsListSettingsProps { settings: Settings; setShortUrlsListSettings: (settings: ShortUrlsSettings) => void; } -export const ShortUrlsListSettings: FC = ( +export const ShortUrlsListSettings: FC = ( { settings: { shortUrlsList }, setShortUrlsListSettings }, ) => ( diff --git a/src/short-urls/ShortUrlsFilteringBar.tsx b/src/short-urls/ShortUrlsFilteringBar.tsx index 96643fe1..7c89009f 100644 --- a/src/short-urls/ShortUrlsFilteringBar.tsx +++ b/src/short-urls/ShortUrlsFilteringBar.tsx @@ -1,7 +1,10 @@ +import { FC } from 'react'; import { faTags as tagsIcon } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { isEmpty, pipe } from 'ramda'; import { parseISO } from 'date-fns'; +import { Row } from 'reactstrap'; +import classNames from 'classnames'; import SearchField from '../utils/SearchField'; import Tag from '../tags/helpers/Tag'; import { DateRangeSelector } from '../utils/dates/DateRangeSelector'; @@ -11,16 +14,20 @@ import { DateRange } from '../utils/dates/types'; import { supportsAllTagsFiltering } from '../utils/helpers/features'; import { SelectedServer } from '../servers/data'; import { TooltipToggleSwitch } from '../utils/TooltipToggleSwitch'; +import { ExportBtn } from '../utils/ExportBtn'; import { useShortUrlsQuery } from './helpers/hooks'; import './ShortUrlsFilteringBar.scss'; -interface ShortUrlsFilteringProps { +export interface ShortUrlsFilteringProps { selectedServer: SelectedServer; + className?: string; } const dateOrNull = (date?: string) => date ? parseISO(date) : null; -const ShortUrlsFilteringBar = (colorGenerator: ColorGenerator) => ({ selectedServer }: ShortUrlsFilteringProps) => { +const ShortUrlsFilteringBar = (colorGenerator: ColorGenerator): FC => ( + { selectedServer, className }, +) => { const [{ search, tags, startDate, endDate, tagsMode = 'any' }, toFirstPage ] = useShortUrlsQuery(); const selectedTags = tags?.split(',') ?? []; const setDates = pipe( @@ -46,23 +53,24 @@ const ShortUrlsFilteringBar = (colorGenerator: ColorGenerator) => ({ selectedSer ); return ( -
+
-
-
-
- -
+ +
+ {}} />
-
+
+ +
+ {selectedTags.length > 0 && (

diff --git a/src/short-urls/ShortUrlsList.tsx b/src/short-urls/ShortUrlsList.tsx index 4e966653..d4828c7a 100644 --- a/src/short-urls/ShortUrlsList.tsx +++ b/src/short-urls/ShortUrlsList.tsx @@ -15,6 +15,7 @@ import { ShortUrlsTableProps } from './ShortUrlsTable'; import Paginator from './Paginator'; import { useShortUrlsQuery } from './helpers/hooks'; import { ShortUrlsOrderableFields, SHORT_URLS_ORDERABLE_FIELDS } from './data'; +import { ShortUrlsFilteringProps } from './ShortUrlsFilteringBar'; interface ShortUrlsListProps { selectedServer: SelectedServer; @@ -23,12 +24,10 @@ interface ShortUrlsListProps { settings: Settings; } -const ShortUrlsList = (ShortUrlsTable: FC, ShortUrlsFilteringBar: FC) => boundToMercureHub(({ - listShortUrls, - shortUrlsList, - selectedServer, - settings, -}: ShortUrlsListProps) => { +const ShortUrlsList = ( + ShortUrlsTable: FC, + ShortUrlsFilteringBar: FC, +) => boundToMercureHub(({ listShortUrls, shortUrlsList, selectedServer, settings }: ShortUrlsListProps) => { const serverId = getServerId(selectedServer); const { page } = useParams(); const location = useLocation(); @@ -66,7 +65,7 @@ const ShortUrlsList = (ShortUrlsTable: FC, ShortUrlsFilteri return ( <> -
+
diff --git a/src/short-urls/services/provideServices.ts b/src/short-urls/services/provideServices.ts index 82e40f4e..425a04a8 100644 --- a/src/short-urls/services/provideServices.ts +++ b/src/short-urls/services/provideServices.ts @@ -50,7 +50,6 @@ const provideServices = (bottle: Bottle, connect: ConnectDecorator) => { bottle.decorator('QrCodeModal', connect([ 'selectedServer' ])); bottle.serviceFactory('ShortUrlsFilteringBar', ShortUrlsFilteringBar, 'ColorGenerator'); - bottle.decorator('ShortUrlsFilteringBar', connect([ 'selectedServer' ])); // Actions bottle.serviceFactory('listShortUrls', listShortUrls, 'buildShlinkApiClient'); diff --git a/src/utils/ExportBtn.tsx b/src/utils/ExportBtn.tsx new file mode 100644 index 00000000..f4f83cd8 --- /dev/null +++ b/src/utils/ExportBtn.tsx @@ -0,0 +1,17 @@ +import { FC } from 'react'; +import { Button } from 'reactstrap'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { faFileDownload } from '@fortawesome/free-solid-svg-icons'; +import { prettify } from './helpers/numbers'; + +interface ExportBtnProps { + onClick: () => void; + amount?: number; + className?: string; +} + +export const ExportBtn: FC = ({ onClick, className, amount = 0 }) => ( + +); diff --git a/src/visits/VisitsStats.tsx b/src/visits/VisitsStats.tsx index 5dfaaad3..cb0b8e77 100644 --- a/src/visits/VisitsStats.tsx +++ b/src/visits/VisitsStats.tsx @@ -2,7 +2,7 @@ import { isEmpty, propEq, values } from 'ramda'; import { useState, useEffect, useMemo, FC, useRef } from 'react'; import { Button, Progress, Row } from 'reactstrap'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { faCalendarAlt, faMapMarkedAlt, faList, faChartPie, faFileDownload } from '@fortawesome/free-solid-svg-icons'; +import { faCalendarAlt, faMapMarkedAlt, faList, faChartPie } from '@fortawesome/free-solid-svg-icons'; import { IconDefinition } from '@fortawesome/fontawesome-common-types'; import { Route, Routes, Navigate } from 'react-router-dom'; import classNames from 'classnames'; @@ -16,6 +16,7 @@ import { SelectedServer } from '../servers/data'; import { supportsBotVisits } from '../utils/helpers/features'; import { prettify } from '../utils/helpers/numbers'; import { NavPillItem, NavPills } from '../utils/NavPills'; +import { ExportBtn } from '../utils/ExportBtn'; import LineChartCard from './charts/LineChartCard'; import VisitsTable from './VisitsTable'; import { NormalizedOrphanVisit, NormalizedVisit, VisitsFilter, VisitsInfo, VisitsParams } from './types'; @@ -308,14 +309,11 @@ const VisitsStats: FC = ({ > Clear selection {highlightedVisits.length > 0 && <>({prettify(highlightedVisits.length)})} - + />

)} diff --git a/test/visits/VisitsStats.test.tsx b/test/visits/VisitsStats.test.tsx index 1fe1f5c5..ed752d8e 100644 --- a/test/visits/VisitsStats.test.tsx +++ b/test/visits/VisitsStats.test.tsx @@ -1,5 +1,5 @@ import { shallow, ShallowWrapper } from 'enzyme'; -import { Button, Progress } from 'reactstrap'; +import { Progress } from 'reactstrap'; import { sum } from 'ramda'; import { Mock } from 'ts-mockery'; import { Route } from 'react-router-dom'; @@ -13,6 +13,7 @@ import { Settings } from '../../src/settings/reducers/settings'; import { SelectedServer } from '../../src/servers/data'; import { SortableBarChartCard } from '../../src/visits/charts/SortableBarChartCard'; import { DoughnutChartCard } from '../../src/visits/charts/DoughnutChartCard'; +import { ExportBtn } from '../../src/utils/ExportBtn'; describe('', () => { const visits = [ Mock.all(), Mock.all(), Mock.all() ]; @@ -106,7 +107,7 @@ describe('', () => { it('exports CSV when export btn is clicked', () => { const wrapper = createComponent({ visits }); - const exportBtn = wrapper.find(Button).last(); + const exportBtn = wrapper.find(ExportBtn).last(); expect(exportBtn).toHaveLength(1); exportBtn.simulate('click');