mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2024-12-23 17:40:23 +03:00
Remove feature flags for features introduced on Shlink <3.0
This commit is contained in:
parent
21525ef945
commit
768fb1992f
8 changed files with 25 additions and 55 deletions
|
@ -28,7 +28,6 @@ export const Main = (
|
||||||
const [sidebarVisible, toggleSidebar, showSidebar, hideSidebar] = useToggle();
|
const [sidebarVisible, toggleSidebar, showSidebar, hideSidebar] = useToggle();
|
||||||
useEffect(() => hideSidebar(), [location]);
|
useEffect(() => hideSidebar(), [location]);
|
||||||
|
|
||||||
const addNonOrphanVisitsRoute = useFeature('nonOrphanVisits');
|
|
||||||
const addDomainVisitsRoute = useFeature('domainVisits');
|
const addDomainVisitsRoute = useFeature('domainVisits');
|
||||||
const burgerClasses = classNames('menu-layout__burger-icon', { 'menu-layout__burger-icon--active': sidebarVisible });
|
const burgerClasses = classNames('menu-layout__burger-icon', { 'menu-layout__burger-icon--active': sidebarVisible });
|
||||||
const swipeableProps = useSwipeable(showSidebar, hideSidebar);
|
const swipeableProps = useSwipeable(showSidebar, hideSidebar);
|
||||||
|
@ -54,7 +53,7 @@ export const Main = (
|
||||||
<Route path="/tag/:tag/visits/*" element={<TagVisits />} />
|
<Route path="/tag/:tag/visits/*" element={<TagVisits />} />
|
||||||
{addDomainVisitsRoute && <Route path="/domain/:domain/visits/*" element={<DomainVisits />} />}
|
{addDomainVisitsRoute && <Route path="/domain/:domain/visits/*" element={<DomainVisits />} />}
|
||||||
<Route path="/orphan-visits/*" element={<OrphanVisits />} />
|
<Route path="/orphan-visits/*" element={<OrphanVisits />} />
|
||||||
{addNonOrphanVisitsRoute && <Route path="/non-orphan-visits/*" element={<NonOrphanVisits />} />}
|
<Route path="/non-orphan-visits/*" element={<NonOrphanVisits />} />
|
||||||
<Route path="/manage-tags" element={<TagsList />} />
|
<Route path="/manage-tags" element={<TagsList />} />
|
||||||
<Route path="/manage-domains" element={<ManageDomains />} />
|
<Route path="/manage-domains" element={<ManageDomains />} />
|
||||||
<Route
|
<Route
|
||||||
|
|
|
@ -20,7 +20,7 @@ interface DomainDropdownProps {
|
||||||
export const DomainDropdown: FC<DomainDropdownProps> = ({ domain, editDomainRedirects }) => {
|
export const DomainDropdown: FC<DomainDropdownProps> = ({ domain, editDomainRedirects }) => {
|
||||||
const [isModalOpen, toggleModal] = useToggle();
|
const [isModalOpen, toggleModal] = useToggle();
|
||||||
const { isDefault } = domain;
|
const { isDefault } = domain;
|
||||||
const canBeEdited = !isDefault || useFeature('defaultDomainRedirectsEdition');
|
const canBeEdited = !isDefault;
|
||||||
const withVisits = useFeature('domainVisits');
|
const withVisits = useFeature('domainVisits');
|
||||||
const routesPrefix = useRoutesPrefix();
|
const routesPrefix = useRoutesPrefix();
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,6 @@ import type { ShortUrlsList as ShortUrlsListState } from '../short-urls/reducers
|
||||||
import { ITEMS_IN_OVERVIEW_PAGE } from '../short-urls/reducers/shortUrlsList';
|
import { ITEMS_IN_OVERVIEW_PAGE } from '../short-urls/reducers/shortUrlsList';
|
||||||
import type { ShortUrlsTableType } from '../short-urls/ShortUrlsTable';
|
import type { ShortUrlsTableType } from '../short-urls/ShortUrlsTable';
|
||||||
import type { TagsList } from '../tags/reducers/tagsList';
|
import type { TagsList } from '../tags/reducers/tagsList';
|
||||||
import { useFeature } from '../utils/features';
|
|
||||||
import { useRoutesPrefix } from '../utils/routesPrefix';
|
import { useRoutesPrefix } from '../utils/routesPrefix';
|
||||||
import { useSetting } from '../utils/settings';
|
import { useSetting } from '../utils/settings';
|
||||||
import type { VisitsOverview } from '../visits/reducers/visitsOverview';
|
import type { VisitsOverview } from '../visits/reducers/visitsOverview';
|
||||||
|
@ -42,7 +41,6 @@ export const Overview = (
|
||||||
const { loading: loadingTags } = tagsList;
|
const { loading: loadingTags } = tagsList;
|
||||||
const { loading: loadingVisits, nonOrphanVisits, orphanVisits } = visitsOverview;
|
const { loading: loadingVisits, nonOrphanVisits, orphanVisits } = visitsOverview;
|
||||||
const routesPrefix = useRoutesPrefix();
|
const routesPrefix = useRoutesPrefix();
|
||||||
const linkToNonOrphanVisits = useFeature('nonOrphanVisits');
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const visits = useSetting('visits');
|
const visits = useSetting('visits');
|
||||||
|
|
||||||
|
@ -58,7 +56,7 @@ export const Overview = (
|
||||||
<div className="col-lg-6 col-xl-3 mb-3">
|
<div className="col-lg-6 col-xl-3 mb-3">
|
||||||
<VisitsHighlightCard
|
<VisitsHighlightCard
|
||||||
title="Visits"
|
title="Visits"
|
||||||
link={linkToNonOrphanVisits ? `${routesPrefix}/non-orphan-visits` : undefined}
|
link={`${routesPrefix}/non-orphan-visits`}
|
||||||
excludeBots={visits?.excludeBots ?? false}
|
excludeBots={visits?.excludeBots ?? false}
|
||||||
loading={loadingVisits}
|
loading={loadingVisits}
|
||||||
visitsSummary={nonOrphanVisits}
|
visitsSummary={nonOrphanVisits}
|
||||||
|
|
|
@ -8,11 +8,11 @@ import './HighlightCard.scss';
|
||||||
|
|
||||||
export type HighlightCardProps = PropsWithChildren<{
|
export type HighlightCardProps = PropsWithChildren<{
|
||||||
title: string;
|
title: string;
|
||||||
link?: string;
|
link: string;
|
||||||
tooltip?: ReactNode;
|
tooltip?: ReactNode;
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
const buildExtraProps = (link?: string) => (!link ? {} : { tag: Link, to: link });
|
const buildExtraProps = (link: string) => ({ tag: Link, to: link });
|
||||||
|
|
||||||
export const HighlightCard: FC<HighlightCardProps> = ({ children, title, link, tooltip }) => {
|
export const HighlightCard: FC<HighlightCardProps> = ({ children, title, link, tooltip }) => {
|
||||||
const ref = useElementRef<HTMLElement>();
|
const ref = useElementRef<HTMLElement>();
|
||||||
|
@ -20,7 +20,7 @@ export const HighlightCard: FC<HighlightCardProps> = ({ children, title, link, t
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Card innerRef={ref} className="highlight-card" body {...buildExtraProps(link)}>
|
<Card innerRef={ref} className="highlight-card" body {...buildExtraProps(link)}>
|
||||||
{link && <FontAwesomeIcon size="3x" className="highlight-card__link-icon" icon={linkIcon} />}
|
<FontAwesomeIcon size="3x" className="highlight-card__link-icon" icon={linkIcon} />
|
||||||
<CardTitle tag="h5" className="highlight-card__title">{title}</CardTitle>
|
<CardTitle tag="h5" className="highlight-card__title">{title}</CardTitle>
|
||||||
<CardText tag="h2">{children}</CardText>
|
<CardText tag="h2">{children}</CardText>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
|
@ -134,8 +134,6 @@ export const ShortUrlForm = (
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
||||||
const showForwardQueryControl = useFeature('forwardQuery');
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form name="shortUrlForm" className="short-url-form" onSubmit={submit}>
|
<form name="shortUrlForm" className="short-url-form" onSubmit={submit}>
|
||||||
{isBasicMode && basicComponents}
|
{isBasicMode && basicComponents}
|
||||||
|
@ -242,7 +240,6 @@ export const ShortUrlForm = (
|
||||||
>
|
>
|
||||||
Make it crawlable
|
Make it crawlable
|
||||||
</ShortUrlFormCheckboxGroup>
|
</ShortUrlFormCheckboxGroup>
|
||||||
{showForwardQueryControl && (
|
|
||||||
<ShortUrlFormCheckboxGroup
|
<ShortUrlFormCheckboxGroup
|
||||||
infoTooltip="When this short URL is visited, any query params appended to it will be forwarded to the long URL."
|
infoTooltip="When this short URL is visited, any query params appended to it will be forwarded to the long URL."
|
||||||
checked={shortUrlData.forwardQuery}
|
checked={shortUrlData.forwardQuery}
|
||||||
|
@ -250,7 +247,6 @@ export const ShortUrlForm = (
|
||||||
>
|
>
|
||||||
Forward query params on redirect
|
Forward query params on redirect
|
||||||
</ShortUrlFormCheckboxGroup>
|
</ShortUrlFormCheckboxGroup>
|
||||||
)}
|
|
||||||
</SimpleCard>
|
</SimpleCard>
|
||||||
</div>
|
</div>
|
||||||
</Row>
|
</Row>
|
||||||
|
|
|
@ -58,7 +58,6 @@ export const ShortUrlsFilteringBar = (
|
||||||
(searchTerm) => toFirstPage({ search: searchTerm }),
|
(searchTerm) => toFirstPage({ search: searchTerm }),
|
||||||
);
|
);
|
||||||
const changeTagSelection = (selectedTags: string[]) => toFirstPage({ tags: selectedTags });
|
const changeTagSelection = (selectedTags: string[]) => toFirstPage({ tags: selectedTags });
|
||||||
const canChangeTagsMode = useFeature('allTagsFiltering');
|
|
||||||
const toggleTagsMode = pipe(
|
const toggleTagsMode = pipe(
|
||||||
() => (tagsMode === 'any' ? 'all' : 'any'),
|
() => (tagsMode === 'any' ? 'all' : 'any'),
|
||||||
(mode) => toFirstPage({ tagsMode: mode }),
|
(mode) => toFirstPage({ tagsMode: mode }),
|
||||||
|
@ -70,7 +69,7 @@ export const ShortUrlsFilteringBar = (
|
||||||
|
|
||||||
<InputGroup className="mt-3">
|
<InputGroup className="mt-3">
|
||||||
<TagsSelector allowNew={false} placeholder="With tags..." selectedTags={tags} onChange={changeTagSelection} />
|
<TagsSelector allowNew={false} placeholder="With tags..." selectedTags={tags} onChange={changeTagSelection} />
|
||||||
{canChangeTagsMode && tags.length > 1 && (
|
{tags.length > 1 && (
|
||||||
<>
|
<>
|
||||||
<Button outline color="secondary" onClick={toggleTagsMode} id="tagsModeBtn" aria-label="Change tags mode">
|
<Button outline color="secondary" onClick={toggleTagsMode} id="tagsModeBtn" aria-label="Change tags mode">
|
||||||
<FontAwesomeIcon className="short-urls-filtering-bar__tags-icon" icon={tagsMode === 'all' ? faTags : faTag} />
|
<FontAwesomeIcon className="short-urls-filtering-bar__tags-icon" icon={tagsMode === 'all' ? faTags : faTag} />
|
||||||
|
|
|
@ -7,7 +7,6 @@ import type { ImageDownloader } from '../../../common/services/ImageDownloader';
|
||||||
import { CopyToClipboardIcon } from '../../../utils/CopyToClipboardIcon';
|
import { CopyToClipboardIcon } from '../../../utils/CopyToClipboardIcon';
|
||||||
import type { QrCodeFormat, QrErrorCorrection } from '../../../utils/helpers/qrCodes';
|
import type { QrCodeFormat, QrErrorCorrection } from '../../../utils/helpers/qrCodes';
|
||||||
import { buildQrCodeUrl } from '../../../utils/helpers/qrCodes';
|
import { buildQrCodeUrl } from '../../../utils/helpers/qrCodes';
|
||||||
import { useFeature } from '../../utils/features';
|
|
||||||
import type { ShortUrlModalProps } from '../data';
|
import type { ShortUrlModalProps } from '../data';
|
||||||
import { QrErrorCorrectionDropdown } from './qr-codes/QrErrorCorrectionDropdown';
|
import { QrErrorCorrectionDropdown } from './qr-codes/QrErrorCorrectionDropdown';
|
||||||
import { QrFormatDropdown } from './qr-codes/QrFormatDropdown';
|
import { QrFormatDropdown } from './qr-codes/QrFormatDropdown';
|
||||||
|
@ -20,7 +19,6 @@ export const QrCodeModal = (imageDownloader: ImageDownloader) => (
|
||||||
const [margin, setMargin] = useState(0);
|
const [margin, setMargin] = useState(0);
|
||||||
const [format, setFormat] = useState<QrCodeFormat>('png');
|
const [format, setFormat] = useState<QrCodeFormat>('png');
|
||||||
const [errorCorrection, setErrorCorrection] = useState<QrErrorCorrection>('L');
|
const [errorCorrection, setErrorCorrection] = useState<QrErrorCorrection>('L');
|
||||||
const displayDownloadBtn = useFeature('nonRestCors');
|
|
||||||
const qrCodeUrl = useMemo(
|
const qrCodeUrl = useMemo(
|
||||||
() => buildQrCodeUrl(shortUrl, { size, format, margin, errorCorrection }),
|
() => buildQrCodeUrl(shortUrl, { size, format, margin, errorCorrection }),
|
||||||
[shortUrl, size, format, margin, errorCorrection],
|
[shortUrl, size, format, margin, errorCorrection],
|
||||||
|
@ -79,7 +77,6 @@ export const QrCodeModal = (imageDownloader: ImageDownloader) => (
|
||||||
<CopyToClipboardIcon text={qrCodeUrl} />
|
<CopyToClipboardIcon text={qrCodeUrl} />
|
||||||
</div>
|
</div>
|
||||||
<img src={qrCodeUrl} className="qr-code-modal__img" alt="QR code" />
|
<img src={qrCodeUrl} className="qr-code-modal__img" alt="QR code" />
|
||||||
{displayDownloadBtn && (
|
|
||||||
<div className="mt-3">
|
<div className="mt-3">
|
||||||
<Button
|
<Button
|
||||||
block
|
block
|
||||||
|
@ -91,7 +88,6 @@ export const QrCodeModal = (imageDownloader: ImageDownloader) => (
|
||||||
Download <FontAwesomeIcon icon={downloadIcon} className="ms-1" />
|
Download <FontAwesomeIcon icon={downloadIcon} className="ms-1" />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</ModalBody>
|
</ModalBody>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
|
@ -3,15 +3,6 @@ import type { SemVer } from '../../utils/helpers/version';
|
||||||
import { versionMatch } from '../../utils/helpers/version';
|
import { versionMatch } from '../../utils/helpers/version';
|
||||||
|
|
||||||
const supportedFeatures = {
|
const supportedFeatures = {
|
||||||
// Deprecated
|
|
||||||
forwardQuery: '2.9.0',
|
|
||||||
nonRestCors: '2.9.0',
|
|
||||||
defaultDomainRedirectsEdition: '2.10.0',
|
|
||||||
nonOrphanVisits: '3.0.0',
|
|
||||||
allTagsFiltering: '3.0.0',
|
|
||||||
tagsStats: '3.0.0',
|
|
||||||
// End deprecated
|
|
||||||
|
|
||||||
domainVisits: '3.1.0',
|
domainVisits: '3.1.0',
|
||||||
excludeBotsOnShortUrls: '3.4.0',
|
excludeBotsOnShortUrls: '3.4.0',
|
||||||
filterDisabledUrls: '3.4.0',
|
filterDisabledUrls: '3.4.0',
|
||||||
|
@ -26,15 +17,6 @@ export const isFeatureEnabledForVersion = (feature: Feature, serverVersion: SemV
|
||||||
versionMatch(serverVersion, { minVersion: supportedFeatures[feature] });
|
versionMatch(serverVersion, { minVersion: supportedFeatures[feature] });
|
||||||
|
|
||||||
const getFeaturesForVersion = (serverVersion: SemVer): Record<Feature, boolean> => ({
|
const getFeaturesForVersion = (serverVersion: SemVer): Record<Feature, boolean> => ({
|
||||||
// Deprecated
|
|
||||||
forwardQuery: isFeatureEnabledForVersion('forwardQuery', serverVersion),
|
|
||||||
nonRestCors: isFeatureEnabledForVersion('nonRestCors', serverVersion),
|
|
||||||
defaultDomainRedirectsEdition: isFeatureEnabledForVersion('defaultDomainRedirectsEdition', serverVersion),
|
|
||||||
nonOrphanVisits: isFeatureEnabledForVersion('nonOrphanVisits', serverVersion),
|
|
||||||
allTagsFiltering: isFeatureEnabledForVersion('allTagsFiltering', serverVersion),
|
|
||||||
tagsStats: isFeatureEnabledForVersion('tagsStats', serverVersion),
|
|
||||||
// End
|
|
||||||
|
|
||||||
domainVisits: isFeatureEnabledForVersion('domainVisits', serverVersion),
|
domainVisits: isFeatureEnabledForVersion('domainVisits', serverVersion),
|
||||||
excludeBotsOnShortUrls: isFeatureEnabledForVersion('excludeBotsOnShortUrls', serverVersion),
|
excludeBotsOnShortUrls: isFeatureEnabledForVersion('excludeBotsOnShortUrls', serverVersion),
|
||||||
filterDisabledUrls: isFeatureEnabledForVersion('filterDisabledUrls', serverVersion),
|
filterDisabledUrls: isFeatureEnabledForVersion('filterDisabledUrls', serverVersion),
|
||||||
|
|
Loading…
Reference in a new issue