Skip to content

Commit 26d955f

Browse files
initial ticket changes
1 parent e085841 commit 26d955f

File tree

3 files changed

+161
-2
lines changed

3 files changed

+161
-2
lines changed
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import { createNoopLogger } from '@mongodb-js/compass-logging/provider';
2+
import { Preferences, type PreferencesAccess } from './preferences';
3+
import type { UserPreferences } from './preferences-schema';
4+
import { type AllPreferences } from './preferences-schema';
5+
import { InMemoryStorage } from './preferences-in-memory-storage';
6+
import { getActiveUser } from './utils';
7+
8+
export class CompassWebPreferencesAccess implements PreferencesAccess {
9+
private _preferences: Preferences;
10+
constructor(preferencesOverrides?: Partial<AllPreferences>) {
11+
this._preferences = new Preferences({
12+
logger: createNoopLogger(),
13+
preferencesStorage: new InMemoryStorage(preferencesOverrides),
14+
});
15+
}
16+
17+
savePreferences(_attributes: Partial<UserPreferences>) {
18+
if (
19+
Object.keys(_attributes).length === 1 &&
20+
'optInDataExplorerGenAIFeatures' in _attributes
21+
) {
22+
return Promise.resolve(this._preferences.savePreferences(_attributes));
23+
}
24+
// do not save any attributes other than the optInDataExplorerGenAIFeatures setting
25+
return Promise.resolve(this._preferences.getPreferences());
26+
}
27+
28+
refreshPreferences() {
29+
return Promise.resolve(this._preferences.getPreferences());
30+
}
31+
32+
getPreferences() {
33+
return this._preferences.getPreferences();
34+
}
35+
36+
ensureDefaultConfigurableUserPreferences() {
37+
return this._preferences.ensureDefaultConfigurableUserPreferences();
38+
}
39+
40+
getConfigurableUserPreferences() {
41+
return Promise.resolve(this._preferences.getConfigurableUserPreferences());
42+
}
43+
44+
getPreferenceStates() {
45+
return Promise.resolve(this._preferences.getPreferenceStates());
46+
}
47+
48+
onPreferenceValueChanged<K extends keyof AllPreferences>(
49+
preferenceName: K,
50+
callback: (value: AllPreferences[K]) => void
51+
) {
52+
return (
53+
this._preferences?.onPreferencesChanged?.(
54+
(preferences: Partial<AllPreferences>) => {
55+
if (Object.keys(preferences).includes(preferenceName)) {
56+
return callback((preferences as AllPreferences)[preferenceName]);
57+
}
58+
}
59+
) ??
60+
(() => {
61+
/* no fallback */
62+
})
63+
);
64+
}
65+
66+
createSandbox() {
67+
return Promise.resolve(
68+
new CompassWebPreferencesAccess(this.getPreferences())
69+
);
70+
}
71+
72+
getPreferencesUser() {
73+
return getActiveUser(this);
74+
}
75+
}

packages/compass-preferences-model/src/preferences-schema.ts

Lines changed: 85 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ export type UserConfigurablePreferences = PermanentFeatureFlags &
5656
| 'web-sandbox-atlas-local'
5757
| 'web-sandbox-atlas-dev'
5858
| 'web-sandbox-atlas';
59+
optInDataExplorerGenAIFeatures: boolean;
5960
// Features that are enabled by default in Compass, but are disabled in Data
6061
// Explorer
6162
enableExplainPlan: boolean;
@@ -115,7 +116,9 @@ export type NonUserPreferences = {
115116
export type AllPreferences = UserPreferences &
116117
CliOnlyPreferences &
117118
NonUserPreferences &
118-
PermanentFeatureFlags;
119+
PermanentFeatureFlags &
120+
AtlasProjectPreferences &
121+
AtlasOrgPreferences;
119122

120123
// Types related to PreferenceDefinition
121124
type PostProcessFunction<T> = (
@@ -210,6 +213,15 @@ export type StoredPreferencesValidator = ReturnType<
210213

211214
export type StoredPreferences = z.output<StoredPreferencesValidator>;
212215

216+
export type AtlasProjectPreferences = {
217+
enableGenAIFeaturesAtlasProject?: boolean;
218+
enableGenAISampleDocumentPassingOnAtlasProject?: boolean;
219+
};
220+
221+
export type AtlasOrgPreferences = {
222+
enableGenAIFeaturesAtlasOrg?: boolean;
223+
};
224+
213225
// Preference definitions
214226
const featureFlagsProps: Required<{
215227
[K in keyof FeatureFlags]: PreferenceDefinition<K>;
@@ -461,7 +473,10 @@ export const storedUserPreferencesProps: Required<{
461473
short: 'Enable AI Features',
462474
long: 'Allow the use of AI features in Compass which make requests to 3rd party services.',
463475
},
464-
deriveValue: deriveNetworkTrafficOptionState('enableGenAIFeatures'),
476+
deriveValue: deriveValueFromOtherPreferences('enableGenAIFeatures', [
477+
'enableGenAIFeaturesAtlasOrg',
478+
'networkTraffic',
479+
]),
465480
validator: z.boolean().default(true),
466481
type: 'boolean',
467482
},
@@ -679,6 +694,16 @@ export const storedUserPreferencesProps: Required<{
679694
.default('atlas'),
680695
type: 'string',
681696
},
697+
optInDataExplorerGenAIFeatures: {
698+
ui: true,
699+
cli: false,
700+
global: false,
701+
description: {
702+
short: 'User Opt-in for Data Explorer Gen AI Features',
703+
},
704+
validator: z.boolean().default(true),
705+
type: 'boolean',
706+
},
682707

683708
enableAtlasSearchIndexes: {
684709
ui: true,
@@ -1007,12 +1032,54 @@ const nonUserPreferences: Required<{
10071032
},
10081033
};
10091034

1035+
const atlasProjectPreferencesProps: Required<{
1036+
[K in keyof NonUserPreferences]: PreferenceDefinition<K>;
1037+
}> = {
1038+
enableGenAIFeaturesAtlasProject: {
1039+
ui: true,
1040+
cli: true,
1041+
global: true,
1042+
description: {
1043+
short: 'Enable Gen AI Features on Atlas Project Level',
1044+
},
1045+
validator: z.boolean().default(true),
1046+
type: 'boolean',
1047+
},
1048+
enableGenAISampleDocumentPassingOnAtlasProject: {
1049+
ui: true,
1050+
cli: true,
1051+
global: true,
1052+
description: {
1053+
short: 'Enable Gen AI Sample Document Passing on Atlas Project Level',
1054+
},
1055+
validator: z.boolean().default(true),
1056+
type: 'boolean',
1057+
},
1058+
};
1059+
1060+
const atlasOrgPreferencesProps: Required<{
1061+
[K in keyof NonUserPreferences]: PreferenceDefinition<K>;
1062+
}> = {
1063+
enableGenAIFeaturesAtlasOrg: {
1064+
ui: true,
1065+
cli: true,
1066+
global: true,
1067+
description: {
1068+
short: 'Enable Gen AI Features on Atlas Org Level',
1069+
},
1070+
validator: z.boolean().default(true),
1071+
type: 'boolean',
1072+
},
1073+
};
1074+
10101075
export const allPreferencesProps: Required<{
10111076
[K in keyof AllPreferences]: PreferenceDefinition<K>;
10121077
}> = {
10131078
...storedUserPreferencesProps,
10141079
...cliOnlyPreferencesProps,
10151080
...nonUserPreferences,
1081+
...atlasProjectPreferencesProps,
1082+
...atlasOrgPreferencesProps,
10161083
};
10171084

10181085
/** Helper for defining how to derive value/state for networkTraffic-affected preferences */
@@ -1027,6 +1094,22 @@ function deriveNetworkTrafficOptionState<K extends keyof AllPreferences>(
10271094
});
10281095
}
10291096

1097+
/** Helper for deriving value/state for preferences from other preferences */
1098+
function deriveValueFromOtherPreferences<K extends keyof AllPreferences>(
1099+
property: K,
1100+
preferencesToDeriveFrom: K[]
1101+
): DeriveValueFunction<boolean> {
1102+
return (v, s) => ({
1103+
value: v(property) && preferencesToDeriveFrom.every((p) => v(p)),
1104+
state:
1105+
s(property) ??
1106+
(preferencesToDeriveFrom.every((p) => v(p))
1107+
? preferencesToDeriveFrom.map((p) => s(p)).filter(Boolean)?.[0] ??
1108+
'derived'
1109+
: undefined),
1110+
});
1111+
}
1112+
10301113
/** Helper for defining how to derive value/state for feature-restricting preferences */
10311114
function deriveFeatureRestrictingOptionsState<K extends keyof AllPreferences>(
10321115
property: K

packages/compass-preferences-model/src/provider.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
export * from './react';
22
export { ReadOnlyPreferenceAccess } from './read-only-preferences-access';
3+
export { CompassWebPreferencesAccess } from './compass-web-preferences-access';
34
export {
45
useIsAIFeatureEnabled,
56
isAIFeatureEnabled,

0 commit comments

Comments
 (0)