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
6 changes: 6 additions & 0 deletions .changeset/happy-grapes-relate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@knocklabs/client": patch
"@knocklabs/react": patch
---

[Guides] Add a Open in dashboard button to guide toolbar v2
1 change: 1 addition & 0 deletions packages/client/src/clients/guide/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ export interface GuideData<TContent = Any> {
activation_url_rules: GuideActivationUrlRuleData[];
activation_url_patterns: GuideActivationUrlPatternData[];
bypass_global_group_limit: boolean;
dashboard_url: string | null;
inserted_at: string;
updated_at: string;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Button } from "@telegraph/button";
import { Box, Stack } from "@telegraph/layout";
import { Tooltip } from "@telegraph/tooltip";
import { Text } from "@telegraph/typography";
Expand Down Expand Up @@ -30,7 +31,7 @@ const CardContainer = ({
bg="surface-1"
border="px"
borderColor="gray-4"
style={{ flex: 1 }}
style={{ flex: 1, alignSelf: "stretch" }}
>
<Text as="span" size="0" color="gray" weight="medium">
{title}
Expand Down Expand Up @@ -129,13 +130,13 @@ export const GuideRowDetails = ({
);
}

const { annotation } = guide;
const { annotation, dashboard_url: dashboardUrl } = guide;
const selectableStatusSummary = getSelectableStatusSummary(
annotation.selectable.status,
);

return (
<Stack px="3" py="2" gap="2" direction="row" align="flex-start">
<Stack p="1" gap="2" direction="row" align="flex-start">
<CardContainer title="Eligibility">
<StatusRow
label="Active"
Expand All @@ -156,7 +157,6 @@ export const GuideRowDetails = ({
tooltip="Whether the current user matches the guide's targeting conditions."
/>
</CardContainer>

<CardContainer title="Visibility">
<StatusRow
label="Activation"
Expand Down Expand Up @@ -185,6 +185,22 @@ export const GuideRowDetails = ({
</Tooltip>
</StatusRow>
</CardContainer>
<Stack
direction="column"
justify="flex-end"
gap="1"
style={{ alignSelf: "stretch" }}
>
{dashboardUrl && (
<Button
size="0"
variant="outline"
onClick={() => window.open(dashboardUrl, "_blank", "noopener")}
>
Open in dashboard
</Button>
)}
</Stack>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Empty Stack renders causing unnecessary layout gap

Medium Severity

The wrapping Stack container (lines 188–203) always renders regardless of whether dashboardUrl is truthy. When dashboardUrl is null, the button is hidden but the empty Stack remains in the flex row. Because the parent Stack has gap="2", this empty child creates visible extra spacing to the right of the "Visibility" card, causing a layout inconsistency compared to when the button is present. The conditional check needs to wrap the outer Stack as well, not just the Button.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 65af25d. Configure here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It's fine, non issue as it is only technically nullable. Should always be present.

</Stack>
);
};
Loading