Skip to content

Commit 14e9e6e

Browse files
authored
feat(insights): enable insights by default COMPASS-7000 (#4622)
* feat(insights): enable insights by default * chore(components): clarify comment
1 parent 0993936 commit 14e9e6e

File tree

6 files changed

+50
-14
lines changed

6 files changed

+50
-14
lines changed

packages/compass-components/src/components/signal-popover.tsx

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { useDarkMode } from '../hooks/use-theme';
1616
import { spacing } from '@leafygreen-ui/tokens';
1717
import { GuideCue } from './guide-cue/guide-cue';
1818
import { useEffectOnChange } from '../hooks/use-effect-on-change';
19+
import { rafraf } from '../utils/rafraf';
1920

2021
type SignalTrackingHooks = {
2122
onSignalMount(id: string): void;
@@ -75,6 +76,8 @@ const SignalHooksProvider: React.FunctionComponent<
7576
);
7677
};
7778

79+
const TRANSITION_DURATION_MS = 150;
80+
7881
export type Signal = {
7982
/**
8083
* Unique signal id that will be used to resolve the dismissing logic.
@@ -336,7 +339,7 @@ const transitionStyles = css({
336339
transitionProperty:
337340
'opacity, width, border-radius, color, box-shadow, background-color',
338341
transitionTimingFunction: 'linear',
339-
transitionDuration: '0.15s',
342+
transitionDuration: `${TRANSITION_DURATION_MS}ms`,
340343
});
341344

342345
const badgeStyles = css(
@@ -438,16 +441,16 @@ const SignalPopover: React.FunctionComponent<SignalPopoverProps> = ({
438441
onPopoverOpenChange: _onPopoverOpenChange,
439442
}) => {
440443
const hooks = useContext(TrackingHooksContext);
441-
const [cueOpen, setCueOpen] = useState(false);
442444
const darkMode = useDarkMode(_darkMode);
443445
const [triggerVisible, setTriggerVisible] = useState(true);
444446
const [popoverOpen, setPopoverOpen] = useState(false);
445-
const [hoverProps, isHovered] = useHoverState();
447+
const [hoverProps, isHovered, setHovered] = useHoverState();
446448
const [currentSignalIndex, setCurrentSignalIndex] = useState(0);
447449
const signals = Array.isArray(_signals) ? _signals : [_signals];
448450
const currentSignal = signals[currentSignalIndex];
449451
const multiSignals = signals.length > 1;
450-
const isActive = cueOpen || isHovered || popoverOpen;
452+
const isActive = isHovered || popoverOpen;
453+
451454
const triggerRef = useRef<HTMLButtonElement>(null);
452455

453456
// To make sure we are covering signals added to the signal popover during the
@@ -549,12 +552,20 @@ const SignalPopover: React.FunctionComponent<SignalPopoverProps> = ({
549552
description="Across Compass, you may now see icons like this to clue you in on potential areas of improvement for your data."
550553
buttonText="See insights in action"
551554
onPrimaryButtonClick={() => {
552-
triggerRef.current?.click();
555+
// Because the guide cue is currently in inactive state when this
556+
// button is clicked, the popover position can be calculated
557+
// incorrectly because the expand animation will be triggered at
558+
// the same time as popover show animation. To work around that,
559+
// we will first manually trigger hover state, wait for the transition
560+
// duration, and only then will click the trigger to open the
561+
// popup
562+
setHovered(true);
563+
setTimeout(() => {
564+
rafraf(() => {
565+
triggerRef.current?.click();
566+
});
567+
}, TRANSITION_DURATION_MS);
553568
}}
554-
// So that the insight badge can animate without messing the tooltip
555-
// position
556-
tooltipAlign="right"
557-
onOpenChange={setCueOpen}
558569
trigger={({ ref: guideCueRef }) => {
559570
const props = mergeProps<HTMLButtonElement>(
560571
hoverProps,

packages/compass-components/src/hooks/use-focus-hover.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,11 @@ export function useFocusState(): [
5757
return [mergedProps, focusStateRef.current, focusStateRef];
5858
}
5959

60-
export function useHoverState(): [React.HTMLAttributes<HTMLElement>, boolean] {
60+
export function useHoverState(): [
61+
React.HTMLAttributes<HTMLElement>,
62+
boolean,
63+
React.Dispatch<React.SetStateAction<boolean>>
64+
] {
6165
const [isHovered, setIsHovered] = useState(false);
6266
const hoverProps = {
6367
onMouseEnter() {
@@ -67,5 +71,5 @@ export function useHoverState(): [React.HTMLAttributes<HTMLElement>, boolean] {
6771
setIsHovered(false);
6872
},
6973
};
70-
return [hoverProps, isHovered];
74+
return [hoverProps, isHovered, setIsHovered];
7175
}

packages/compass-e2e-tests/helpers/selectors.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1129,3 +1129,7 @@ export const DuplicateViewModalConfirmButton = `${DuplicateViewModal} button[typ
11291129

11301130
// Modify view
11311131
export const ModifySourceBanner = '[data-testid="modify-source-banner"]';
1132+
1133+
// Insights
1134+
export const InsightIconButton = '[data-testid="insight-badge-button"]';
1135+
export const InsightPopoverCard = '[data-testid="insight-signal-card"]';

packages/compass-e2e-tests/tests/collection-documents-tab.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,4 +562,19 @@ FindIterable<Document> result = collection.find(filter);`);
562562
const noDocuments = await browser.$('.document-list-zero-state');
563563
await noDocuments.waitForDisplayed();
564564
});
565+
566+
it('shows insight for the unindexed query', async function () {
567+
await browser.runFindOperation('Documents', '{ i: 35 }');
568+
await browser.clickVisible(Selectors.InsightIconButton);
569+
await browser.waitForAnimations(Selectors.InsightPopoverCard);
570+
const unindexedQuerySignal = await browser.$(
571+
'strong=Query executed without index'
572+
);
573+
// Looks redundant, but selector above can return a special webdriver
574+
// non-existing element, so we try to get some text so that it will actually
575+
// throw if not found in DOM
576+
expect(await unindexedQuerySignal.getText()).to.eq(
577+
'Query executed without index'
578+
);
579+
});
565580
});

packages/compass-preferences-model/src/feature-flags.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ export const featureFlags: Required<{
8282
},
8383

8484
showInsights: {
85-
stage: 'development',
85+
stage: 'released',
8686
description: {
8787
short: 'Show performance insights',
8888
long: 'Surface visual signals in the Compass interface to highlight potential performance issues and anti-patterns.',

packages/compass-query-bar/src/components/option-editor.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,10 @@ const editorWithErrorStyles = css({
5454

5555
const queryBarEditorOptionInsightsStyles = css({
5656
position: 'absolute',
57-
// Horizontally the insight is in the middle of the first line of the editor
58-
top: `calc((${spacing[4]}px - 18px) / 2)`,
57+
// Horizontally the insight is in the middle of the first line of the editor:
58+
// (input height - insight badge height) / 2 to get the empty space + 1px
59+
// because top indicates where element starts, not where padding ends
60+
top: `calc((${spacing[4]}px - 18px) / 2 + 1px)`,
5961
right: spacing[1],
6062
});
6163

0 commit comments

Comments
 (0)