Delegate tag color storage to ShlinkWebComponent consuming app

This commit is contained in:
Alejandro Celaya
2023-08-06 13:54:57 +02:00
parent 9f9f3b6402
commit 89e75653d7
12 changed files with 53 additions and 65 deletions

View File

@@ -7,12 +7,14 @@ import type { ShlinkApiClient } from './api-contract';
import { FeaturesProvider, useFeatures } from './utils/features';
import type { SemVer } from './utils/helpers/version';
import { RoutesPrefixProvider } from './utils/routesPrefix';
import type { TagColorsStorage } from './utils/services/TagColorsStorage';
import type { Settings } from './utils/settings';
import { SettingsProvider } from './utils/settings';
type ShlinkWebComponentProps = {
serverVersion: SemVer;
serverVersion: SemVer; // FIXME Consider making this optional and trying to resolve it if not set
apiClient: ShlinkApiClient;
tagColorsStorage?: TagColorsStorage;
routesPrefix?: string;
settings?: Settings;
createNotFound?: (nonPrefixedHomePath: string) => ReactNode;
@@ -24,7 +26,7 @@ let apiClientRef: ShlinkApiClient;
export const createShlinkWebComponent = (
bottle: Bottle,
): FC<ShlinkWebComponentProps> => ({ serverVersion, apiClient, settings, routesPrefix = '', createNotFound }) => {
): FC<ShlinkWebComponentProps> => ({ serverVersion, apiClient, settings, routesPrefix = '', createNotFound, tagColorsStorage }) => {
const features = useFeatures(serverVersion);
const mainContent = useRef<ReactNode>();
const [theStore, setStore] = useState<Store | undefined>();
@@ -33,6 +35,10 @@ export const createShlinkWebComponent = (
apiClientRef = apiClient;
bottle.value('apiClientFactory', () => apiClientRef);
if (tagColorsStorage) {
bottle.value('TagColorsStorage', tagColorsStorage);
}
// It's important to not try to resolve services before the API client has been registered, as many other services
// depend on it
const { container } = bottle;
@@ -42,7 +48,7 @@ export const createShlinkWebComponent = (
// Load mercure info
store.dispatch(loadMercureInfo(settings));
}, [apiClient]);
}, [apiClient, tagColorsStorage]);
return !theStore ? <></> : (
<ReduxStoreProvider store={theStore}>

View File

@@ -14,3 +14,5 @@ export type {
TagsSettings,
Settings,
} from './utils/settings';
export type { TagColorsStorage } from './utils/services/TagColorsStorage';

View File

@@ -1,6 +1,6 @@
import { isNil } from 'ramda';
import { rangeOf } from '../helpers';
import type { LocalStorage } from './LocalStorage';
import type { TagColorsStorage } from './TagColorsStorage';
const HEX_COLOR_LENGTH = 6;
const HEX_DIGITS = '0123456789ABCDEF';
@@ -19,8 +19,8 @@ export class ColorGenerator {
private readonly colors: Record<string, string>;
private readonly lights: Record<string, boolean>;
public constructor(private readonly storage: LocalStorage) {
this.colors = this.storage.get<Record<string, string>>('colors') ?? {};
public constructor(private readonly storage?: TagColorsStorage) {
this.colors = this.storage?.getTagColors() ?? {};
this.lights = {};
}
@@ -40,7 +40,7 @@ export class ColorGenerator {
const normalizedKey = normalizeKey(key);
this.colors[normalizedKey] = color;
this.storage.set('colors', this.colors);
this.storage?.storeTagColors(this.colors);
return color;
};

View File

@@ -0,0 +1,5 @@
export type TagColorsStorage = {
getTagColors(): Record<string, string>;
storeTagColors(colors: Record<string, string>): void;
};

View File

@@ -3,7 +3,6 @@ import { useTimeoutToggle } from '../helpers/hooks';
import { jsonToCsv } from '../helpers/json';
import { ColorGenerator } from './ColorGenerator';
import { ImageDownloader } from './ImageDownloader';
import { LocalStorage } from './LocalStorage';
import { ReportExporter } from './ReportExporter';
export function provideServices(bottle: Bottle) {
@@ -11,9 +10,7 @@ export function provideServices(bottle: Bottle) {
bottle.constant('fetch', window.fetch.bind(window));
bottle.service('ImageDownloader', ImageDownloader, 'fetch', 'window');
bottle.constant('localStorage', window.localStorage);
bottle.service('Storage', LocalStorage, 'localStorage');
bottle.service('ColorGenerator', ColorGenerator, 'Storage');
bottle.service('ColorGenerator', ColorGenerator, 'TagColorsStorage');
bottle.constant('jsonToCsv', jsonToCsv);
bottle.service('ReportExporter', ReportExporter, 'window', 'jsonToCsv');