@launchdarkly/toolbar 2.5.4-beta.1 → 2.6.1-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cdn/toolbar.min.js +65 -65
- package/dist/core/tests/mocks/providers.d.ts +132 -0
- package/dist/core/ui/Toolbar/components/new/AnalyticsConsentToast/AnalyticsConsentToast.d.ts +5 -0
- package/dist/core/ui/Toolbar/components/new/AnalyticsConsentToast/AnalyticsConsentToast.module.css.d.ts +13 -0
- package/dist/core/ui/Toolbar/components/new/AnalyticsConsentToast/index.d.ts +1 -0
- package/dist/core/ui/Toolbar/components/new/Settings/Privacy/PrivacySettings.d.ts +1 -0
- package/dist/core/ui/Toolbar/components/new/Settings/index.d.ts +1 -1
- package/dist/core/ui/Toolbar/components/new/types.d.ts +1 -1
- package/dist/core/ui/Toolbar/context/state/ToolbarStateProvider.d.ts +6 -0
- package/dist/core/ui/Toolbar/context/telemetry/AnalyticsPreferencesProvider.d.ts +14 -0
- package/dist/core/ui/Toolbar/context/telemetry/index.d.ts +1 -0
- package/dist/core/ui/Toolbar/utils/localStorage.d.ts +12 -2
- package/dist/core/utils/analytics.d.ts +2 -1
- package/dist/index.cjs +1 -1
- package/dist/js/index.js +1 -1
- package/dist/js/react.js +1 -1
- package/dist/react.cjs +1 -1
- package/package.json +4 -4
- package/dist/core/ui/Toolbar/components/new/Settings/SettingsContent.d.ts +0 -1
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { vi } from 'vitest';
|
|
2
|
+
/**
|
|
3
|
+
* Shared mock factory functions for provider contexts.
|
|
4
|
+
*
|
|
5
|
+
* GLOBAL MOCKS:
|
|
6
|
+
* AnalyticsPreferencesProvider is mocked globally in vitest.setup.ts.
|
|
7
|
+
* Most test files don't need to do anything - the mock is automatic.
|
|
8
|
+
*
|
|
9
|
+
* TESTING REAL IMPLEMENTATIONS:
|
|
10
|
+
* If your test file tests the REAL implementation of a provider, add this at
|
|
11
|
+
* the top of your test file:
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* vi.unmock('../ui/Toolbar/context/telemetry/AnalyticsPreferencesProvider');
|
|
15
|
+
*
|
|
16
|
+
* OVERRIDING WITH DYNAMIC VALUES:
|
|
17
|
+
* If your test needs to change mock values during execution, override the
|
|
18
|
+
* global mock with createDynamicAnalyticsPreferencesProviderMock:
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* const { getMockValue, setMockValue } = vi.hoisted(() => {
|
|
22
|
+
* let value = false;
|
|
23
|
+
* return { getMockValue: () => value, setMockValue: (v) => { value = v; } };
|
|
24
|
+
* });
|
|
25
|
+
*
|
|
26
|
+
* vi.mock('../ui/Toolbar/context/telemetry/AnalyticsPreferencesProvider', async () => {
|
|
27
|
+
* const { createDynamicAnalyticsPreferencesProviderMock } = await import('./mocks/providers');
|
|
28
|
+
* return createDynamicAnalyticsPreferencesProviderMock({ getIsOptedInToAnalytics: getMockValue });
|
|
29
|
+
* });
|
|
30
|
+
*/
|
|
31
|
+
interface AnalyticsPreferencesMock {
|
|
32
|
+
useAnalyticsPreferences: () => {
|
|
33
|
+
isOptedInToAnalytics: boolean;
|
|
34
|
+
isOptedInToEnhancedAnalytics: boolean;
|
|
35
|
+
isOptedInToSessionReplay: boolean;
|
|
36
|
+
handleToggleAnalyticsOptOut: ReturnType<typeof vi.fn>;
|
|
37
|
+
handleToggleEnhancedAnalyticsOptOut: ReturnType<typeof vi.fn>;
|
|
38
|
+
handleToggleSessionReplayOptOut: ReturnType<typeof vi.fn>;
|
|
39
|
+
};
|
|
40
|
+
AnalyticsPreferencesProvider: ({ children }: {
|
|
41
|
+
children: React.ReactNode;
|
|
42
|
+
}) => React.ReactNode;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Creates a mock for AnalyticsPreferencesProvider.
|
|
46
|
+
* Used by vitest.setup.ts for global mocking.
|
|
47
|
+
*/
|
|
48
|
+
export declare function createAnalyticsPreferencesProviderMock(overrides?: {
|
|
49
|
+
isOptedInToAnalytics?: boolean;
|
|
50
|
+
isOptedInToEnhancedAnalytics?: boolean;
|
|
51
|
+
isOptedInToSessionReplay?: boolean;
|
|
52
|
+
}): AnalyticsPreferencesMock;
|
|
53
|
+
/**
|
|
54
|
+
* Creates a mock for AnalyticsPreferencesProvider with dynamic values.
|
|
55
|
+
* Use this when you need to change mock values during test execution.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* // For dynamic isOptedInToAnalytics:
|
|
59
|
+
* let mockIsOptedIn = false;
|
|
60
|
+
* vi.mock('../ui/Toolbar/context/telemetry/AnalyticsPreferencesProvider', async () => {
|
|
61
|
+
* const { createDynamicAnalyticsPreferencesProviderMock } = await import('./mocks/providers');
|
|
62
|
+
* return createDynamicAnalyticsPreferencesProviderMock({ getIsOptedInToAnalytics: () => mockIsOptedIn });
|
|
63
|
+
* });
|
|
64
|
+
*
|
|
65
|
+
* // For dynamic isOptedInToEnhancedAnalytics:
|
|
66
|
+
* vi.mock('../ui/Toolbar/context/telemetry/AnalyticsPreferencesProvider', async () => {
|
|
67
|
+
* const { createDynamicAnalyticsPreferencesProviderMock } = await import('./mocks/providers');
|
|
68
|
+
* return createDynamicAnalyticsPreferencesProviderMock({ getIsOptedInToEnhancedAnalytics: () => mockValue });
|
|
69
|
+
* });
|
|
70
|
+
*
|
|
71
|
+
* // In tests:
|
|
72
|
+
* mockIsOptedIn = true; // Changes mock behavior
|
|
73
|
+
*/
|
|
74
|
+
export declare function createDynamicAnalyticsPreferencesProviderMock(options: {
|
|
75
|
+
getIsOptedInToAnalytics?: () => boolean;
|
|
76
|
+
getIsOptedInToEnhancedAnalytics?: () => boolean;
|
|
77
|
+
getIsOptedInToSessionReplay?: () => boolean;
|
|
78
|
+
}): AnalyticsPreferencesMock;
|
|
79
|
+
/**
|
|
80
|
+
* Creates a mock for InternalClientProvider with a customizable mock LDClient.
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* const mockLDClient = { track: vi.fn(), ... };
|
|
84
|
+
* vi.mock('../../ui/Toolbar/context/telemetry/InternalClientProvider', () =>
|
|
85
|
+
* createInternalClientProviderMock(mockLDClient)
|
|
86
|
+
* );
|
|
87
|
+
*/
|
|
88
|
+
export declare function createInternalClientProviderMock(mockClient?: Record<string, unknown>): {
|
|
89
|
+
useInternalClient: () => {
|
|
90
|
+
client: Record<string, unknown> | null;
|
|
91
|
+
loading: boolean;
|
|
92
|
+
error: null;
|
|
93
|
+
updateContext: ReturnType<typeof vi.fn>;
|
|
94
|
+
};
|
|
95
|
+
InternalClientProvider: ({ children }: {
|
|
96
|
+
children: React.ReactNode;
|
|
97
|
+
}) => React.ReactNode;
|
|
98
|
+
};
|
|
99
|
+
/**
|
|
100
|
+
* Creates a mock for DevServerProvider.
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* vi.mock('../../ui/Toolbar/context/DevServerProvider', () =>
|
|
104
|
+
* createDevServerProviderMock({ connectionStatus: 'connected' })
|
|
105
|
+
* );
|
|
106
|
+
*/
|
|
107
|
+
export declare function createDevServerProviderMock(overrides?: {
|
|
108
|
+
sourceEnvironmentKey?: string;
|
|
109
|
+
connectionStatus?: string;
|
|
110
|
+
flags?: Record<string, unknown>;
|
|
111
|
+
isLoading?: boolean;
|
|
112
|
+
error?: Error | null;
|
|
113
|
+
}): {
|
|
114
|
+
useDevServerContext: () => {
|
|
115
|
+
state: {
|
|
116
|
+
sourceEnvironmentKey: string;
|
|
117
|
+
connectionStatus: string;
|
|
118
|
+
flags: Record<string, unknown>;
|
|
119
|
+
lastSyncTime: number;
|
|
120
|
+
isLoading: boolean;
|
|
121
|
+
error: Error | null;
|
|
122
|
+
};
|
|
123
|
+
setOverride: ReturnType<typeof vi.fn>;
|
|
124
|
+
clearOverride: ReturnType<typeof vi.fn>;
|
|
125
|
+
clearAllOverrides: ReturnType<typeof vi.fn>;
|
|
126
|
+
refresh: ReturnType<typeof vi.fn>;
|
|
127
|
+
};
|
|
128
|
+
DevServerProvider: ({ children }: {
|
|
129
|
+
children: React.ReactNode;
|
|
130
|
+
}) => React.ReactNode;
|
|
131
|
+
};
|
|
132
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare const overlay: string;
|
|
2
|
+
export declare const container: string;
|
|
3
|
+
export declare const infoIcon: string;
|
|
4
|
+
export declare const content: string;
|
|
5
|
+
export declare const textContent: string;
|
|
6
|
+
export declare const title: string;
|
|
7
|
+
export declare const description: string;
|
|
8
|
+
export declare const privacyLink: string;
|
|
9
|
+
export declare const actions: string;
|
|
10
|
+
export declare const button: string;
|
|
11
|
+
export declare const primaryButton: string;
|
|
12
|
+
export declare const closeButton: string;
|
|
13
|
+
export declare const closeIcon: string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { AnalyticsConsentToast } from './AnalyticsConsentToast';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function PrivacySettings(): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export type FlagsSubtab = 'flags' | 'contexts';
|
|
2
2
|
export type MonitoringSubtab = 'events';
|
|
3
|
-
export type SettingsSubtab = 'general';
|
|
3
|
+
export type SettingsSubtab = 'general' | 'privacy';
|
|
4
4
|
export type InteractiveSubtab = 'workflows';
|
|
5
5
|
export type SubTab = FlagsSubtab | MonitoringSubtab | SettingsSubtab | InteractiveSubtab;
|
|
6
6
|
export interface TabConfig {
|
|
@@ -10,6 +10,9 @@ export interface ToolbarStateContextValue {
|
|
|
10
10
|
reloadOnFlagChangeIsEnabled: boolean;
|
|
11
11
|
isAutoCollapseEnabled: boolean;
|
|
12
12
|
mode: ToolbarMode;
|
|
13
|
+
isOptedInToAnalytics: boolean;
|
|
14
|
+
isOptedInToEnhancedAnalytics: boolean;
|
|
15
|
+
isOptedInToSessionReplay: boolean;
|
|
13
16
|
toolbarRef: React.RefObject<HTMLDivElement | null>;
|
|
14
17
|
handleTabChange: (tabId: string) => void;
|
|
15
18
|
handleClose: () => void;
|
|
@@ -19,6 +22,9 @@ export interface ToolbarStateContextValue {
|
|
|
19
22
|
handleCircleClick: () => void;
|
|
20
23
|
setIsAnimating: Dispatch<SetStateAction<boolean>>;
|
|
21
24
|
setSearchIsExpanded: Dispatch<SetStateAction<boolean>>;
|
|
25
|
+
handleToggleAnalyticsOptOut: (enabled: boolean) => void;
|
|
26
|
+
handleToggleEnhancedAnalyticsOptOut: (enabled: boolean) => void;
|
|
27
|
+
handleToggleSessionReplayOptOut: (enabled: boolean) => void;
|
|
22
28
|
}
|
|
23
29
|
export interface ToolbarStateProviderProps {
|
|
24
30
|
children: ReactNode;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
export interface AnalyticsPreferencesContextValue {
|
|
3
|
+
isOptedInToAnalytics: boolean;
|
|
4
|
+
isOptedInToEnhancedAnalytics: boolean;
|
|
5
|
+
isOptedInToSessionReplay: boolean;
|
|
6
|
+
handleToggleAnalyticsOptOut: (enabled: boolean) => void;
|
|
7
|
+
handleToggleEnhancedAnalyticsOptOut: (enabled: boolean) => void;
|
|
8
|
+
handleToggleSessionReplayOptOut: (enabled: boolean) => void;
|
|
9
|
+
}
|
|
10
|
+
export interface AnalyticsPreferencesProviderProps {
|
|
11
|
+
children: ReactNode;
|
|
12
|
+
}
|
|
13
|
+
export declare function AnalyticsPreferencesProvider({ children }: AnalyticsPreferencesProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
export declare function useAnalyticsPreferences(): AnalyticsPreferencesContextValue;
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import type { LDContext } from 'launchdarkly-js-client-sdk';
|
|
2
2
|
import { ToolbarPosition } from '../types/toolbar';
|
|
3
3
|
export declare const TOOLBAR_STORAGE_KEYS: {
|
|
4
|
-
readonly ENVIRONMENT: "ld-toolbar-environment";
|
|
5
4
|
readonly SETTINGS: "ld-toolbar-settings";
|
|
6
5
|
readonly DISABLED: "ld-toolbar-disabled";
|
|
7
|
-
readonly PROJECT: "ld-toolbar-project";
|
|
8
6
|
readonly STARRED_FLAGS: "ld-toolbar-starred-flags";
|
|
9
7
|
readonly MCP_ALERT_DISMISSED: "ld-toolbar-mcp-alert-dismissed";
|
|
8
|
+
readonly ANALYTICS_CONSENT_SHOWN: "ld-toolbar-analytics-consent-shown";
|
|
10
9
|
readonly CONTEXTS: "ld-toolbar-contexts";
|
|
11
10
|
readonly ACTIVE_CONTEXT: "ld-toolbar-active-context";
|
|
12
11
|
};
|
|
@@ -17,6 +16,9 @@ export interface ToolbarSettings {
|
|
|
17
16
|
reloadOnFlagChange: boolean;
|
|
18
17
|
autoCollapse: boolean;
|
|
19
18
|
preferredIde: PreferredIde;
|
|
19
|
+
isOptedInToAnalytics: boolean;
|
|
20
|
+
isOptedInToEnhancedAnalytics: boolean;
|
|
21
|
+
isOptedInToSessionReplay: boolean;
|
|
20
22
|
}
|
|
21
23
|
export declare const DEFAULT_SETTINGS: ToolbarSettings;
|
|
22
24
|
export declare function saveToolbarPosition(position: ToolbarPosition): void;
|
|
@@ -35,3 +37,11 @@ export declare function loadContexts(): Array<LDContext>;
|
|
|
35
37
|
export declare function saveContexts(contexts: Array<LDContext>): void;
|
|
36
38
|
export declare function loadActiveContext(): LDContext | null;
|
|
37
39
|
export declare function saveActiveContext(context: LDContext | null): void;
|
|
40
|
+
export declare function saveIsOptedInToAnalytics(isOptedInToAnalytics: boolean): void;
|
|
41
|
+
export declare function loadIsOptedInToAnalytics(): boolean;
|
|
42
|
+
export declare function saveIsOptedInToEnhancedAnalytics(isOptedInToEnhancedAnalytics: boolean): void;
|
|
43
|
+
export declare function saveIsOptedInToSessionReplay(isOptedInToSessionReplay: boolean): void;
|
|
44
|
+
export declare function loadIsOptedInToSessionReplay(): boolean;
|
|
45
|
+
export declare function loadIsOptedInToEnhancedAnalytics(): boolean;
|
|
46
|
+
export declare function saveAnalyticsConsentShown(shown: boolean): void;
|
|
47
|
+
export declare function loadAnalyticsConsentShown(): boolean;
|
|
@@ -8,8 +8,9 @@ export declare const ANALYTICS_EVENT_PREFIX = "ld.toolbar";
|
|
|
8
8
|
export declare class ToolbarAnalytics {
|
|
9
9
|
private ldClient;
|
|
10
10
|
private mode;
|
|
11
|
+
private isOptedInToAnalytics;
|
|
11
12
|
private searchDebounceTimer;
|
|
12
|
-
constructor(ldClient?: LDClient | null, mode?: ToolbarMode);
|
|
13
|
+
constructor(ldClient?: LDClient | null, mode?: ToolbarMode, isOptedInToAnalytics?: boolean);
|
|
13
14
|
/**
|
|
14
15
|
* Internal method to send tracking events
|
|
15
16
|
*/
|
package/dist/index.cjs
CHANGED
|
@@ -552,7 +552,7 @@ async function lazyLoad(signal, url) {
|
|
|
552
552
|
throw new Error(`Could not load LaunchDarkly developer toolbar bundle from ${url}`);
|
|
553
553
|
}
|
|
554
554
|
}
|
|
555
|
-
var package_namespaceObject = JSON.parse('{"rE":"2.
|
|
555
|
+
var package_namespaceObject = JSON.parse('{"rE":"2.6.1-beta.1"}');
|
|
556
556
|
function useLaunchDarklyToolbar(args) {
|
|
557
557
|
const { toolbarBundleUrl, enabled, ...initConfig } = args;
|
|
558
558
|
const configRef = (0, external_react_namespaceObject.useRef)(null);
|
package/dist/js/index.js
CHANGED
|
@@ -518,7 +518,7 @@ async function lazyLoad(signal, url) {
|
|
|
518
518
|
throw new Error(`Could not load LaunchDarkly developer toolbar bundle from ${url}`);
|
|
519
519
|
}
|
|
520
520
|
}
|
|
521
|
-
var package_namespaceObject = JSON.parse('{"rE":"2.
|
|
521
|
+
var package_namespaceObject = JSON.parse('{"rE":"2.6.1-beta.1"}');
|
|
522
522
|
function useLaunchDarklyToolbar(args) {
|
|
523
523
|
const { toolbarBundleUrl, enabled, ...initConfig } = args;
|
|
524
524
|
const configRef = useRef(null);
|
package/dist/js/react.js
CHANGED
|
@@ -49,7 +49,7 @@ async function lazyLoad(signal, url) {
|
|
|
49
49
|
throw new Error(`Could not load LaunchDarkly developer toolbar bundle from ${url}`);
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
|
-
var package_namespaceObject = JSON.parse('{"rE":"2.
|
|
52
|
+
var package_namespaceObject = JSON.parse('{"rE":"2.6.1-beta.1"}');
|
|
53
53
|
function useLaunchDarklyToolbar(args) {
|
|
54
54
|
const { toolbarBundleUrl, enabled, ...initConfig } = args;
|
|
55
55
|
const configRef = useRef(null);
|
package/dist/react.cjs
CHANGED
|
@@ -78,7 +78,7 @@ async function lazyLoad(signal, url) {
|
|
|
78
78
|
throw new Error(`Could not load LaunchDarkly developer toolbar bundle from ${url}`);
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
|
-
var package_namespaceObject = JSON.parse('{"rE":"2.
|
|
81
|
+
var package_namespaceObject = JSON.parse('{"rE":"2.6.1-beta.1"}');
|
|
82
82
|
function useLaunchDarklyToolbar(args) {
|
|
83
83
|
const { toolbarBundleUrl, enabled, ...initConfig } = args;
|
|
84
84
|
const configRef = (0, external_react_namespaceObject.useRef)(null);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"private": false,
|
|
3
3
|
"name": "@launchdarkly/toolbar",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.6.1-beta.1",
|
|
5
5
|
"description": "A framework-agnostic developer toolbar for interacting with LaunchDarkly during development",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"launchdarkly",
|
|
@@ -91,7 +91,7 @@
|
|
|
91
91
|
}
|
|
92
92
|
},
|
|
93
93
|
"devDependencies": {
|
|
94
|
-
"@codemirror/commands": "^6.10.
|
|
94
|
+
"@codemirror/commands": "^6.10.1",
|
|
95
95
|
"@codemirror/lang-json": "^6.0.2",
|
|
96
96
|
"@codemirror/language": "^6.11.3",
|
|
97
97
|
"@codemirror/lint": "^6.9.2",
|
|
@@ -114,7 +114,7 @@
|
|
|
114
114
|
"@storybook/addon-onboarding": "^10.1.7",
|
|
115
115
|
"@storybook/blocks": "^9.0.0-alpha.17",
|
|
116
116
|
"@storybook/react": "^10.0.8",
|
|
117
|
-
"@storybook/react-vite": "^10.1.
|
|
117
|
+
"@storybook/react-vite": "^10.1.10",
|
|
118
118
|
"@storybook/test": "^9.0.0-alpha.2",
|
|
119
119
|
"@tanstack/react-virtual": "^3.13.13",
|
|
120
120
|
"@testing-library/jest-dom": "^6.9.1",
|
|
@@ -134,7 +134,7 @@
|
|
|
134
134
|
"react": "^19.2.3",
|
|
135
135
|
"react-dom": "^19.2.3",
|
|
136
136
|
"storybook": "^10.1.4",
|
|
137
|
-
"storybook-addon-rslib": "^3.
|
|
137
|
+
"storybook-addon-rslib": "^3.2.0",
|
|
138
138
|
"storybook-react-rsbuild": "^3.1.0",
|
|
139
139
|
"typescript": "^5.9.3",
|
|
140
140
|
"vitest": "^4.0.15"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function SettingsContent(): import("react/jsx-runtime").JSX.Element;
|