Skip to content

Commit

Permalink
Add visibility badge to header (#10542)
Browse files Browse the repository at this point in the history
When clicked, this badge opens the share modal dialog
  • Loading branch information
bvaughn authored May 28, 2024
1 parent f620e9e commit 0fa3c9a
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 12 deletions.
33 changes: 25 additions & 8 deletions packages/replay-next/components/Icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ export type IconType =
| "folder-open"
| "hide"
| "inspect"
| "invisible"
| "invoke-getter"
| "log-point-panel-arrow-above"
| "log-point-panel-arrow-below"
Expand Down Expand Up @@ -91,7 +90,9 @@ export type IconType =
| "view-component-source"
| "view-function-source"
| "view-html-element"
| "visible"
| "visibility-private"
| "visibility-public"
| "visibility-team"
| "warning"
| "whole-word"
| "regex";
Expand Down Expand Up @@ -305,10 +306,6 @@ export default function Icon({
</>
);
break;
case "invisible":
path =
"M12 7c2.76 0 5 2.24 5 5 0 .65-.13 1.26-.36 1.83l2.92 2.92c1.51-1.26 2.7-2.89 3.43-4.75-1.73-4.39-6-7.5-11-7.5-1.4 0-2.74.25-3.98.7l2.16 2.16C10.74 7.13 11.35 7 12 7zM2 4.27l2.28 2.28.46.46C3.08 8.3 1.78 10.02 1 12c1.73 4.39 6 7.5 11 7.5 1.55 0 3.03-.3 4.38-.84l.42.42L19.73 22 21 20.73 3.27 3 2 4.27zM7.53 9.8l1.55 1.55c-.05.21-.08.43-.08.65 0 1.66 1.34 3 3 3 .22 0 .44-.03.65-.08l1.55 1.55c-.67.33-1.41.53-2.2.53-2.76 0-5-2.24-5-5 0-.79.2-1.53.53-2.2zm4.31-.78l3.15 3.15.02-.16c0-1.66-1.34-3-3-3l-.17.01z";
break;
case "invoke-getter":
path = (
<>
Expand Down Expand Up @@ -680,9 +677,29 @@ export default function Icon({
path =
"M5 15H3v4c0 1.1.9 2 2 2h4v-2H5v-4zM5 5h4V3H5c-1.1 0-2 .9-2 2v4h2V5zm14-2h-4v2h4v4h2V5c0-1.1-.9-2-2-2zm0 16h-4v2h4c1.1 0 2-.9 2-2v-4h-2v4zM12 9c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z";
break;
case "visible":
case "visibility-private":
path =
"M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z";
"M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm-6 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zm3.1-9H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2z";
break;
case "visibility-public":
path =
"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 17.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L9 15v1c0 1.1.9 2 2 2v1.93zm6.9-2.54c-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H8v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41c2.93 1.19 5 4.06 5 7.41 0 2.08-.8 3.97-2.1 5.39z";
break;
case "visibility-team":
path = (
<g>
<path
d="M16.67,13.13C18.04,14.06,19,15.32,19,17v3h4v-3 C23,14.82,19.43,13.53,16.67,13.13z"
fillRule="evenodd"
/>
<circle cx="9" cy="8" fillRule="evenodd" r="4" />
<path
d="M15,12c2.21,0,4-1.79,4-4c0-2.21-1.79-4-4-4c-0.47,0-0.91,0.1-1.33,0.24 C14.5,5.27,15,6.58,15,8s-0.5,2.73-1.33,3.76C14.09,11.9,14.53,12,15,12z"
fillRule="evenodd"
/>
<path d="M9,13c-2.67,0-8,1.34-8,4v3h16v-3C17,14.34,11.67,13,9,13z" fillRule="evenodd" />
</g>
);
break;
case "warning":
path = "M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z";
Expand Down
23 changes: 23 additions & 0 deletions src/ui/components/Header/Header.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,26 @@
transform: rotate(180deg);
margin: 2px 2px 0 6px;
}

.VisibilityIcon {
width: 1rem;
height: 1rem;
}

.VisibilityIconAndText {
flex-shrink: 0;
display: flex;
flex-direction: row;
align-items: center;
gap: 1ch;
font-size: var(--font-size-regular);
background-color: var(--body-bgcolor);
border-radius: 1rem;
overflow: hidden;
padding: 0.25rem 0.5rem;
cursor: pointer;
}

.VisibilityIconAndText:hover {
background-color: var(--title-hover-bgcolor);
}
36 changes: 32 additions & 4 deletions src/ui/components/Header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,20 @@ import classNames from "classnames";
import { useRouter } from "next/router";
import { ClipboardEvent, KeyboardEvent, useLayoutEffect, useRef, useState } from "react";

import Icon, { IconType } from "replay-next/components/Icon";
import { useNag } from "replay-next/src/hooks/useNag";
import { RecordingTarget } from "replay-next/src/suspense/BuildIdCache";
import { Recording } from "shared/graphql/types";
import { Nag, Recording } from "shared/graphql/types";
import { selectAll } from "shared/utils/selection";
import { getAccessToken, getRecordingTarget } from "ui/actions/app";
import { getAccessToken, getRecordingTarget, setModal } from "ui/actions/app";
import Avatar from "ui/components/Avatar";
import UserOptions from "ui/components/Header/UserOptions";
import ViewToggle, { shouldShowDevToolsNag } from "ui/components/Header/ViewToggle";
import IconWithTooltip from "ui/components/shared/IconWithTooltip";
import hooks from "ui/hooks";
import { useGetActiveSessions } from "ui/hooks/sessions";
import { getViewMode } from "ui/reducers/layout";
import { useAppSelector } from "ui/setup/hooks";
import { useAppDispatch, useAppSelector } from "ui/setup/hooks";
import { trackEvent } from "ui/utils/telemetry";

import { isTestSuiteReplay } from "../TestSuite/utils/isTestSuiteReplay";
Expand Down Expand Up @@ -169,9 +171,13 @@ export default function Header() {
const recordingTarget = useAppSelector(getRecordingTarget);
const isAuthenticated = !!useAppSelector(getAccessToken);
const recordingId = hooks.useGetRecordingId();
const { recording, loading } = hooks.useGetRecording(recordingId);
const { loading, recording } = hooks.useGetRecording(recordingId);
const backIcon = <div className={classNames(styles.BackButton, "img", "arrowhead-right")} />;

const dispatch = useAppDispatch();

const [, dismissShareNag] = useNag(Nag.SHARE); // Properly call useNag and destructure dismissShareNag

if (loading) {
return <div className={styles.Header}></div>;
}
Expand All @@ -197,6 +203,25 @@ export default function Header() {
}
}

let iconType: IconType;
let visibilityLabel: string;
if (!recording.private) {
iconType = "visibility-public";
visibilityLabel = "Public";
} else if (recording.workspace) {
iconType = "visibility-team";
visibilityLabel = "Team";
} else {
iconType = "visibility-private";
visibilityLabel = "Private";
}

const onClick = () => {
trackEvent("header.open_share");
dismissShareNag();
dispatch(setModal("sharing", { recordingId: recordingId! }));
};

return (
<div className={styles.Header}>
<div className="relative flex flex-grow flex-row items-center overflow-hidden">
Expand All @@ -210,6 +235,9 @@ export default function Header() {
) : (
<div className={styles.ReadOnlyTitle}>Recordings</div>
)}
<button className={styles.VisibilityIconAndText} onClick={onClick}>
<Icon className={styles.VisibilityIcon} type={iconType} /> {visibilityLabel}
</button>
<div className="flex-grow">&nbsp;</div>
</div>
<Links recordingTarget={recordingTarget} />
Expand Down

0 comments on commit 0fa3c9a

Please sign in to comment.