Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/compass-collection/src/stores/collection-tab.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ export function activatePlugin(
store.dispatch(selectTab('Aggregations'));
});

on(localAppRegistry, 'menu-share-schema-json', () => {
store.dispatch(selectTab('Schema'));
});

void collectionModel.fetchMetadata({ dataService }).then((metadata) => {
store.dispatch(collectionMetadataFetched(metadata));
});
Expand Down
2 changes: 2 additions & 0 deletions packages/compass-schema/src/components/compass-schema.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import type { RootState } from '../stores/store';
import { startAnalysis, stopAnalysis } from '../stores/schema-analysis-reducer';
import { openExportSchema } from '../stores/schema-export-reducer';
import ExportSchemaModal from './export-schema-modal';
import ExportSchemaLegacyBanner from './export-schema-legacy-banner';

const rootStyles = css({
width: '100%',
Expand Down Expand Up @@ -431,6 +432,7 @@ const Schema: React.FunctionComponent<{
</WorkspaceContainer>
</div>
{enableExportSchema && <ExportSchemaModal />}
{enableExportSchema && <ExportSchemaLegacyBanner />}
</>
);
};
Expand Down

Large diffs are not rendered by default.

51 changes: 0 additions & 51 deletions packages/compass-schema/src/stores/schema-analysis-reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import {
schemaContainsGeoData,
} from '../modules/schema-analysis';
import { capMaxTimeMSAtPreferenceLimit } from 'compass-preferences-model/provider';
import { openToast } from '@mongodb-js/compass-components';
import type { Circle, Layer, LayerGroup, Polygon } from 'leaflet';
import { mongoLogId } from '@mongodb-js/compass-logging/provider';
import type { SchemaThunkAction } from './store';
Expand Down Expand Up @@ -126,56 +125,6 @@ function resultId(): string {
return new UUID().toString();
}

export const handleSchemaShare = (): SchemaThunkAction<void> => {
return (dispatch, getState, { namespace }) => {
const {
schemaAnalysis: { schema },
} = getState();
const hasSchema = schema !== null;
if (hasSchema) {
void navigator.clipboard.writeText(JSON.stringify(schema, null, ' '));
}
dispatch(_trackSchemaShared(hasSchema));
openToast(
'share-schema',
hasSchema
? {
variant: 'success',
title: 'Schema Copied',
description: `The schema definition of ${namespace} has been copied to your clipboard in JSON format.`,
timeout: 5_000,
}
: {
variant: 'warning',
title: 'Analyze Schema First',
description: 'Please Analyze the Schema First from the Schema Tab.',
timeout: 5_000,
}
);
};
};

export const _trackSchemaShared = (
hasSchema: boolean
): SchemaThunkAction<void> => {
return (dispatch, getState, { track, connectionInfoRef }) => {
const {
schemaAnalysis: { schema },
} = getState();
// Use a function here to a) ensure that the calculations here
// are only made when telemetry is enabled and b) that errors from
// those calculations are caught and logged rather than displayed to
// users as errors from the core schema sharing logic.
const trackEvent = () => ({
has_schema: hasSchema,
schema_width: schema?.fields?.length ?? 0,
schema_depth: schema ? calculateSchemaDepth(schema) : 0,
geo_data: schema ? schemaContainsGeoData(schema) : false,
});
track('Schema Exported', trackEvent, connectionInfoRef.current);
};
};

const getInitialState = (): SchemaAnalysisState => ({
analysisState: ANALYSIS_STATE_INITIAL,
errorMessage: '',
Expand Down
157 changes: 156 additions & 1 deletion packages/compass-schema/src/stores/schema-export-reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ import type {

import type { SchemaThunkAction } from './store';
import { isAction } from '../utils';
import type { SchemaAccessor } from '../modules/schema-analysis';
import {
calculateSchemaDepth,
schemaContainsGeoData,
type SchemaAccessor,
} from '../modules/schema-analysis';
import { openToast } from '@mongodb-js/compass-components';

export type SchemaFormat =
| 'standardJSON'
Expand All @@ -20,6 +25,8 @@ export type ExportStatus = 'inprogress' | 'complete' | 'error';
export type SchemaExportState = {
abortController?: AbortController;
isOpen: boolean;
isLegacyBannerOpen: boolean;
legacyBannerChoice?: 'legacy' | 'export';
exportedSchema?: string;
exportFormat: SchemaFormat;
errorMessage?: string;
Expand All @@ -34,11 +41,16 @@ const getInitialState = (): SchemaExportState => ({
exportStatus: 'inprogress',
exportedSchema: undefined,
isOpen: false,
isLegacyBannerOpen: false,
legacyBannerChoice: undefined,
});

export const enum SchemaExportActions {
openExportSchema = 'schema-service/schema-export/openExportSchema',
closeExportSchema = 'schema-service/schema-export/closeExportSchema',
openLegacyBanner = 'schema-service/schema-export/openLegacyBanner',
closeLegacyBanner = 'schema-service/schema-export/closeLegacyBanner',
setLegacyBannerChoice = 'schema-service/schema-export/setLegacyBannerChoice',
changeExportSchemaStatus = 'schema-service/schema-export/changeExportSchemaStatus',
changeExportSchemaFormatStarted = 'schema-service/schema-export/changeExportSchemaFormatStarted',
changeExportSchemaFormatComplete = 'schema-service/schema-export/changeExportSchemaFormatComplete',
Expand Down Expand Up @@ -263,6 +275,42 @@ export const schemaExportReducer: Reducer<SchemaExportState, Action> = (
};
}

if (
isAction<openLegacyBannerAction>(
action,
SchemaExportActions.openLegacyBanner
)
) {
return {
...state,
isLegacyBannerOpen: true,
};
}

if (
isAction<closeLegacyBannerAction>(
action,
SchemaExportActions.closeLegacyBanner
)
) {
return {
...state,
isLegacyBannerOpen: false,
};
}

if (
isAction<setLegacyBannerChoiceAction>(
action,
SchemaExportActions.setLegacyBannerChoice
)
) {
return {
...state,
legacyBannerChoice: action.choice,
};
}

if (
isAction<ChangeExportSchemaFormatStartedAction>(
action,
Expand Down Expand Up @@ -319,3 +367,110 @@ export const schemaExportReducer: Reducer<SchemaExportState, Action> = (

return state;
};

// TODO clean out when phase out is confirmed COMPASS-8692
export type openLegacyBannerAction = {
type: SchemaExportActions.openLegacyBanner;
};

export const openLegacyBanner = (): SchemaThunkAction<void> => {
return (dispatch, getState) => {
const choiceInState = getState().schemaExport.legacyBannerChoice;
const savedChoice = choiceInState || localStorage.getItem(localStorageId);
if (savedChoice) {
if (savedChoice !== choiceInState) {
dispatch({
type: SchemaExportActions.setLegacyBannerChoice,
choice: savedChoice,
});
}
if (savedChoice === 'legacy') {
dispatch(confirmedLegacySchemaShare());
return;
}
if (savedChoice === 'export') {
dispatch(openExportSchema());
return;
}
}
dispatch({ type: SchemaExportActions.openLegacyBanner });
};
};

export type closeLegacyBannerAction = {
type: SchemaExportActions.closeLegacyBanner;
};

export type setLegacyBannerChoiceAction = {
type: SchemaExportActions.setLegacyBannerChoice;
choice: 'legacy' | 'export';
};

const localStorageId = 'schemaExportLegacyBannerChoice';

export const switchToSchemaExport = (): SchemaThunkAction<void> => {
return (dispatch) => {
dispatch({ type: SchemaExportActions.closeLegacyBanner });
dispatch(openExportSchema());
};
};

export const confirmedLegacySchemaShare = (): SchemaThunkAction<void> => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Calling out that in a branch I'm working on I've updated all the share wording to be export for the internals, so we have some more consistency. In case someone brings it up.

return (dispatch, getState, { namespace }) => {
const {
schemaAnalysis: { schema },
} = getState();
const hasSchema = schema !== null;
if (hasSchema) {
void navigator.clipboard.writeText(JSON.stringify(schema, null, ' '));
}
dispatch(_trackSchemaShared(hasSchema));
dispatch({ type: SchemaExportActions.closeLegacyBanner });
openToast(
'share-schema',
hasSchema
? {
variant: 'success',
title: 'Schema Copied',
description: `The schema definition of ${namespace} has been copied to your clipboard in JSON format.`,
timeout: 5_000,
}
: {
variant: 'warning',
title: 'Analyze Schema First',
description:
'Please analyze the schema in the schema tab before sharing the schema.',
}
);
};
};

export const _trackSchemaShared = (
hasSchema: boolean
): SchemaThunkAction<void> => {
return (dispatch, getState, { track, connectionInfoRef }) => {
const {
schemaAnalysis: { schema },
} = getState();
// Use a function here to a) ensure that the calculations here
// are only made when telemetry is enabled and b) that errors from
// those calculations are caught and logged rather than displayed to
// users as errors from the core schema sharing logic.
const trackEvent = () => ({
has_schema: hasSchema,
schema_width: schema?.fields?.length ?? 0,
schema_depth: schema ? calculateSchemaDepth(schema) : 0,
geo_data: schema ? schemaContainsGeoData(schema) : false,
});
track('Schema Exported', trackEvent, connectionInfoRef.current);
};
};

export const stopShowingLegacyBanner = (
choice: 'legacy' | 'export'
): SchemaThunkAction<void> => {
return (dispatch) => {
localStorage.setItem(localStorageId, choice);
dispatch({ type: SchemaExportActions.setLegacyBannerChoice, choice });
};
};
19 changes: 11 additions & 8 deletions packages/compass-schema/src/stores/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,11 @@ import type { PreferencesAccess } from 'compass-preferences-model/provider';
import type { FieldStoreService } from '@mongodb-js/compass-field-store';
import type { QueryBarService } from '@mongodb-js/compass-query-bar';
import type { TrackFunction } from '@mongodb-js/compass-telemetry';
import {
schemaAnalysisReducer,
handleSchemaShare,
stopAnalysis,
} from './schema-analysis-reducer';
import { schemaAnalysisReducer, stopAnalysis } from './schema-analysis-reducer';
import {
cancelExportSchema,
confirmedLegacySchemaShare,
openLegacyBanner,
schemaExportReducer,
} from './schema-export-reducer';
import type { InternalLayer } from '../modules/geo';
Expand Down Expand Up @@ -78,9 +76,14 @@ export function activateSchemaPlugin(
* When `Share Schema as JSON` clicked in menu show a dialog message.
*/

on(services.localAppRegistry, 'menu-share-schema-json', () =>
store.dispatch(handleSchemaShare())
);
on(services.localAppRegistry, 'menu-share-schema-json', () => {
const { enableExportSchema } = services.preferences.getPreferences();
if (enableExportSchema) {
store.dispatch(openLegacyBanner());
return;
}
store.dispatch(confirmedLegacySchemaShare());
});

addCleanup(() => store.dispatch(stopAnalysis()));
addCleanup(() => store.dispatch(cancelExportSchema()));
Expand Down
4 changes: 2 additions & 2 deletions packages/compass/src/main/menu.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ describe('CompassMenu', function () {
submenu: [
{
accelerator: 'Alt+CmdOrCtrl+S',
label: '&Share Schema as JSON',
label: '&Share Schema as JSON (Legacy)',
},
{
type: 'separator',
Expand Down Expand Up @@ -445,7 +445,7 @@ describe('CompassMenu', function () {
submenu: [
{
accelerator: 'Alt+CmdOrCtrl+S',
label: '&Share Schema as JSON',
label: '&Share Schema as JSON (Legacy)',
},
{
type: 'separator',
Expand Down
2 changes: 1 addition & 1 deletion packages/compass/src/main/menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ function collectionSubMenu(
): MenuItemConstructorOptions {
const subMenu = [];
subMenu.push({
label: '&Share Schema as JSON',
label: '&Share Schema as JSON (Legacy)',
accelerator: 'Alt+CmdOrCtrl+S',
click() {
ipcMain?.broadcastFocused('window:menu-share-schema-json');
Expand Down
Loading