Skip to content

Commit

Permalink
feat(databases-collections, collection): add "Visualize Your Data" bu…
Browse files Browse the repository at this point in the history
…tton to workspace headers CLOUDP-247464 (#5917)

* feat(collection): add "Visualize your data" CTA to the Collection tab header

* feat(databased-collections): show breadcrumb on the databases list; add visualize cta; make header stick to the top of the tab

* chore(e2e): update selectors
  • Loading branch information
gribnoysup authored Jul 2, 2024
1 parent ea45c8a commit dd60120
Show file tree
Hide file tree
Showing 13 changed files with 278 additions and 218 deletions.
10 changes: 8 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { useConnectionInfo } from '@mongodb-js/compass-connections/provider';
import { useOpenWorkspace } from '@mongodb-js/compass-workspaces/provider';
import React from 'react';
import { usePreference } from 'compass-preferences-model/provider';
import toNS from 'mongodb-ns';

const collectionHeaderActionsStyles = css({
display: 'flex',
Expand All @@ -17,6 +18,20 @@ const collectionHeaderActionsStyles = css({
gap: spacing[2],
});

function buildChartsUrl(
groupId: string,
clusterName: string,
namespace: string
) {
const { database, collection } = toNS(namespace);
const url = new URL(`/charts/${groupId}`, window.location.origin);
url.searchParams.set('sourceType', 'cluster');
url.searchParams.set('instanceName', clusterName);
url.searchParams.set('database', database);
url.searchParams.set('collection', collection);
return url.toString();
}

type CollectionHeaderActionsProps = {
namespace: string;
isReadonly: boolean;
Expand All @@ -34,7 +49,7 @@ const CollectionHeaderActions: React.FunctionComponent<
sourceName,
sourcePipeline,
}: CollectionHeaderActionsProps) => {
const { id: connectionId } = useConnectionInfo();
const { id: connectionId, atlasMetadata } = useConnectionInfo();
const { openCollectionWorkspace, openEditViewWorkspace } = useOpenWorkspace();
const preferencesReadOnly = usePreference('readOnly');

Expand All @@ -43,6 +58,22 @@ const CollectionHeaderActions: React.FunctionComponent<
className={collectionHeaderActionsStyles}
data-testid="collection-header-actions"
>
{atlasMetadata && (
<Button
data-testid="collection-header-visualize-your-data"
size={ButtonSize.Small}
href={buildChartsUrl(
atlasMetadata.projectId,
atlasMetadata.clusterName,
namespace
)}
target="_self"
rel="noopener noreferrer"
leftGlyph={<Icon glyph="Charts" />}
>
Visualize Your Data
</Button>
)}
{isReadonly && sourceName && !editViewName && !preferencesReadOnly && (
<Button
data-testid="collection-header-actions-edit-button"
Expand Down
21 changes: 16 additions & 5 deletions packages/compass-components/src/components/workspace-container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,14 @@ function WorkspaceContainer({
initialTopInView = true,
'data-testid': dataTestId,
...props
}: React.PropsWithChildren<
WorkspaceContainerProps & React.HTMLProps<HTMLDivElement>
>) {
}: WorkspaceContainerProps &
React.HTMLProps<HTMLDivElement> & {
children:
| React.ReactNode
| ((
scrollTriggerRef: (node?: Element | null | undefined) => void
) => React.ReactNode);
}) {
const darkMode = useDarkMode();

const scrollContainer = useRef(null);
Expand Down Expand Up @@ -158,8 +163,14 @@ function WorkspaceContainer({
</div>
)}
<div ref={scrollableContainerRef} className={workspaceContentStyles}>
<div ref={scrollDetectionTrigger}></div>
{children}
{typeof children === 'function' ? (
children(scrollDetectionTrigger)
) : (
<>
<div ref={scrollDetectionTrigger}></div>
{children}
</>
)}
</div>
</div>
</div>
Expand Down
8 changes: 4 additions & 4 deletions packages/compass-e2e-tests/helpers/selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -468,9 +468,9 @@ export const ShellOutput = '[data-testid="shell-output"]';
// Instance screen
export const DatabasesTable = '[data-testid="database-grid"]';
export const InstanceCreateDatabaseButton =
'[data-testid="database-grid"] [data-testid="create-controls"] button';
'[data-testid="create-controls"] button';
export const InstanceRefreshDatabaseButton =
'[data-testid="database-grid"] [data-testid="refresh-controls"] button';
'[data-testid="refresh-controls"] button';
export const DatabaseCard = '[data-testid="database-grid-item"]';
// assume that there's only one hovered card at a time and that the first and only button is the drop button
export const DatabaseCardDrop =
Expand All @@ -491,9 +491,9 @@ export const databaseCardClickable = (dbName: string): string => {
// Database screen
export const CollectionsGrid = '[data-testid="collection-grid"]';
export const DatabaseCreateCollectionButton =
'[data-testid="collection-grid"] [data-testid="create-controls"] button';
'[data-testid="create-controls"] button';
export const DatabaseRefreshCollectionButton =
'[data-testid="collection-grid"] [data-testid="refresh-controls"] button';
'[data-testid="refresh-controls"] button';
export const CollectionCard = '[data-testid="collection-grid-item"]';
// assume that there's only one hovered card at a time and that the first and only button is the drop button
export const CollectionCardDrop =
Expand Down
4 changes: 4 additions & 0 deletions packages/databases-collections-list/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,12 @@
},
"dependencies": {
"@mongodb-js/compass-components": "^1.26.1",
"@mongodb-js/compass-connections": "^1.34.0",
"@mongodb-js/compass-telemetry": "^1.1.0",
"@mongodb-js/compass-workspaces": "^0.15.0",
"@mongodb-js/connection-info": "^0.5.0",
"compass-preferences-model": "^2.24.0",
"mongodb-ns": "^2.4.2",
"react": "^17.0.2"
},
"devDependencies": {
Expand Down
38 changes: 5 additions & 33 deletions packages/databases-collections-list/src/collections.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
/* eslint-disable react/prop-types */
import React, { useMemo } from 'react';
import {
type BreadcrumbItem,
Breadcrumbs,
css,
spacing,
} from '@mongodb-js/compass-components';
import React from 'react';
import { css, spacing } from '@mongodb-js/compass-components';
import { compactBytes, compactNumber } from './format';
import type { BadgeProp } from './namespace-card';
import { NamespaceItemCard } from './namespace-card';
Expand Down Expand Up @@ -86,47 +80,25 @@ const pageContainerStyles = css({
flexDirection: 'column',
});

const breadcrumbStyles = css({
paddingLeft: spacing[3],
paddingTop: spacing[3],
paddingBottom: spacing[2],
});

const CollectionsList: React.FunctionComponent<{
connectionTitle: string;
databaseName: string;
namespace: string;
collections: Collection[];
onCollectionClick(id: string): void;
onClickConnectionBreadcrumb(): void;
onDeleteCollectionClick?: (id: string) => void;
onCreateCollectionClick?: () => void;
onRefreshClick?: () => void;
}> = ({
connectionTitle,
databaseName,
namespace,
collections,
onClickConnectionBreadcrumb,
onCollectionClick,
onCreateCollectionClick,
onDeleteCollectionClick,
onRefreshClick,
}) => {
const breadcrumbItems = useMemo(() => {
return [
{
name: connectionTitle,
onClick: () => onClickConnectionBreadcrumb(),
},
{
name: databaseName,
},
] as BreadcrumbItem[];
}, [connectionTitle, databaseName, onClickConnectionBreadcrumb]);

return (
<div className={pageContainerStyles}>
<Breadcrumbs className={breadcrumbStyles} items={breadcrumbItems} />
<ItemsGrid
namespace={namespace}
items={collections}
itemType="collection"
itemGridWidth={COLLECTION_CARD_WIDTH}
Expand Down
27 changes: 2 additions & 25 deletions packages/databases-collections-list/src/index.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,9 @@ describe('databases and collections list', function () {

render(
<CollectionsList
connectionTitle="My Connection"
databaseName="My Database"
namespace="db"
collections={colls}
onCollectionClick={clickSpy}
onClickConnectionBreadcrumb={() => {}}
></CollectionsList>
);

Expand All @@ -122,32 +120,11 @@ describe('databases and collections list', function () {
expect(clickSpy).to.be.calledWith('bar.bar');
});

it('should notify when the connection name is clicked', function () {
const clickSpy = Sinon.spy();
const connectionClickSpy = Sinon.spy();

render(
<CollectionsList
connectionTitle="My Connection"
databaseName="My Database"
collections={colls}
onClickConnectionBreadcrumb={connectionClickSpy}
onCollectionClick={clickSpy}
></CollectionsList>
);

userEvent.click(screen.getByText('My Connection'));

expect(connectionClickSpy).to.be.called;
});

it('should not display statistics (except storage size) on timeseries collection card', function () {
render(
<CollectionsList
connectionTitle="My Connection"
databaseName="My Database"
namespace="db"
collections={colls}
onClickConnectionBreadcrumb={() => {}}
onCollectionClick={() => {}}
></CollectionsList>
);
Expand Down
Loading

0 comments on commit dd60120

Please sign in to comment.