Extract shlink-web-component outside of src folder

This commit is contained in:
Alejandro Celaya
2023-07-24 20:14:59 +02:00
parent 768fb1992f
commit 3a0cea1268
230 changed files with 485 additions and 524 deletions

View File

@@ -0,0 +1,38 @@
import { createContext, useContext, useMemo } from 'react';
import type { SemVer } from '../../src/utils/helpers/version';
import { versionMatch } from '../../src/utils/helpers/version';
const supportedFeatures = {
domainVisits: '3.1.0',
excludeBotsOnShortUrls: '3.4.0',
filterDisabledUrls: '3.4.0',
deviceLongUrls: '3.5.0',
} as const satisfies Record<string, SemVer>;
Object.freeze(supportedFeatures);
export type Feature = keyof typeof supportedFeatures;
export const isFeatureEnabledForVersion = (feature: Feature, serverVersion: SemVer): boolean =>
versionMatch(serverVersion, { minVersion: supportedFeatures[feature] });
const getFeaturesForVersion = (serverVersion: SemVer): Record<Feature, boolean> => ({
domainVisits: isFeatureEnabledForVersion('domainVisits', serverVersion),
excludeBotsOnShortUrls: isFeatureEnabledForVersion('excludeBotsOnShortUrls', serverVersion),
filterDisabledUrls: isFeatureEnabledForVersion('filterDisabledUrls', serverVersion),
deviceLongUrls: isFeatureEnabledForVersion('deviceLongUrls', serverVersion),
});
export const useFeatures = (serverVersion: SemVer) => useMemo(
() => getFeaturesForVersion(serverVersion),
[serverVersion],
);
const FeaturesContext = createContext(getFeaturesForVersion('0.0.0'));
export const FeaturesProvider = FeaturesContext.Provider;
export const useFeature = (feature: Feature) => {
const features = useContext(FeaturesContext);
return features[feature];
};

View File

@@ -0,0 +1,7 @@
import { createContext, useContext } from 'react';
const RoutesPrefixContext = createContext('');
export const RoutesPrefixProvider = RoutesPrefixContext.Provider;
export const useRoutesPrefix = (): string => useContext(RoutesPrefixContext);

View File

@@ -0,0 +1,83 @@
import { createContext, useContext } from 'react';
import type { DateInterval } from '../../src/utils/helpers/dateIntervals';
import type { Theme } from '../../src/utils/theme';
import type { ShortUrlsOrder } from '../short-urls/data';
import type { TagsOrder } from '../tags/data/TagsListChildrenProps';
export const DEFAULT_SHORT_URLS_ORDERING: ShortUrlsOrder = {
field: 'dateCreated',
dir: 'DESC',
};
/**
* Important! When adding new props in the main Settings interface or any of the nested props, they have to be set as
* optional, as old instances of the app will load partial objects from local storage until it is saved again.
*/
export interface RealTimeUpdatesSettings {
enabled: boolean;
interval?: number;
}
export type TagFilteringMode = 'startsWith' | 'includes';
export interface ShortUrlCreationSettings {
validateUrls: boolean;
tagFilteringMode?: TagFilteringMode;
forwardQuery?: boolean;
}
export interface UiSettings {
theme: Theme;
}
export interface VisitsSettings {
defaultInterval: DateInterval;
excludeBots?: boolean;
}
export interface TagsSettings {
defaultOrdering?: TagsOrder;
}
export interface ShortUrlsListSettings {
defaultOrdering?: ShortUrlsOrder;
}
export interface Settings {
realTimeUpdates?: RealTimeUpdatesSettings;
shortUrlCreation?: ShortUrlCreationSettings;
shortUrlsList?: ShortUrlsListSettings;
ui?: UiSettings;
visits?: VisitsSettings;
tags?: TagsSettings;
}
const defaultSettings: Settings = {
realTimeUpdates: {
enabled: true,
},
shortUrlCreation: {
validateUrls: false,
},
ui: {
theme: 'light',
},
visits: {
defaultInterval: 'last30Days',
},
shortUrlsList: {
defaultOrdering: DEFAULT_SHORT_URLS_ORDERING,
},
};
const SettingsContext = createContext<Settings | undefined>(defaultSettings);
export const SettingsProvider = SettingsContext.Provider;
export const useSettings = (): Settings => useContext(SettingsContext) ?? defaultSettings;
export const useSetting = <T extends keyof Settings>(settingName: T): Settings[T] => {
const settings = useSettings();
return settings[settingName];
};