Skip to content
Closed
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
5 changes: 5 additions & 0 deletions .changeset/tired-bats-rescue.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@knocklabs/react": patch
---

[Guides] Add a settings toggle to filter only active guies in the guide toolbar v2
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,15 @@ import { Toggle } from "@telegraph/toggle";
import { Tooltip } from "@telegraph/tooltip";
import { Text } from "@telegraph/typography";

export const GuideContextDetails = () => {
type Props = {
activeOnly: boolean;
onActiveOnlyChange: (value: boolean) => void;
};

export const GuideContextDetails = ({
activeOnly,
onActiveOnlyChange,
}: Props) => {
const { client } = useGuideContext();
const { debugSettings } = useStore(client.store, (state) => ({
debugSettings: state.debug || {},
Expand Down Expand Up @@ -67,6 +75,26 @@ export const GuideContextDetails = () => {
}}
/>
</Stack>
<Stack direction="row" gap="2" align="center" h="7">
<Tooltip label="Only show guides that are active">
<Text
as="span"
size="1"
weight="medium"
color="gray"
width="36"
mt="1"
>
Active only
</Text>
</Tooltip>
<Toggle.Default
size="1"
pt="1_5"
value={activeOnly}
onValueChange={onActiveOnlyChange}
/>
</Stack>
</Stack>
</Stack>
<Stack direction="column" gap="1" width="full">
Expand Down
65 changes: 39 additions & 26 deletions packages/react/src/modules/guide/components/Toolbar/V2/V2.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,13 @@ const Kbd = ({ children }: { children: React.ReactNode }) => {
const filterGuides = (
guides: InspectionResultOk["guides"],
displayOption: DisplayOption,
opts?: { activeOnly?: boolean },
) => {
return guides.filter((guide) => {
if (opts?.activeOnly && !guide.annotation.active.status) {
return false;
}

const { isEligible, isQualified } = guide.annotation;
const isDisplayable = isEligible && isQualified;

Expand All @@ -72,6 +77,7 @@ export const V2 = () => {

const [displayOption, setDisplayOption] =
React.useState<DisplayOption>("only-eligible");
const [activeOnly, setActiveOnly] = React.useState(false);
const [runConfig, setRunConfig] = React.useState(() => getRunConfig());
const [isCollapsed, setIsCollapsed] = React.useState(false);
const [isContextPanelOpen, setIsContextPanelOpen] = React.useState(false);
Expand Down Expand Up @@ -143,7 +149,30 @@ export const V2 = () => {
}

const guides =
result.status === "ok" ? filterGuides(result.guides, displayOption) : [];
result.status === "ok"
? filterGuides(result.guides, displayOption, { activeOnly })
: [];

// Clear focus lock if the focused guide would be hidden under the given
// filter combination.
const maybeClearStaleFocus = (
nextDisplayOption: DisplayOption,
nextActiveOnly: boolean,
) => {
if (result?.status !== "ok") return;

const debugSettings = client.store.state.debug;
const focusedKeys = Object.keys(debugSettings?.focusedGuideKeys || {});
if (focusedKeys.length === 0) return;

const stillVisible = filterGuides(result.guides, nextDisplayOption, {
activeOnly: nextActiveOnly,
}).find((g) => g.key === focusedKeys[0]);

if (!stillVisible) {
client.setDebug({ ...debugSettings, focusedGuideKeys: {} });
}
};

return (
<Box
Expand Down Expand Up @@ -257,34 +286,12 @@ export const V2 = () => {
value={displayOption}
onValueChange={(val: DisplayOption) => {
if (!val) return;

const debugSettings = client.store.state.debug;

const focusedGuideKeys = Object.keys(
debugSettings?.focusedGuideKeys || {},
);

// Exit out of focus if the currently focused guide is not
// part of the selected list filter.
if (result.status === "ok" && focusedGuideKeys.length > 0) {
const currFocusedGuide = filterGuides(
result.guides,
val,
).find((g) => g.key === focusedGuideKeys[0]);

if (!currFocusedGuide) {
client.setDebug({
...debugSettings,
focusedGuideKeys: {},
});
}
}

maybeClearStaleFocus(val, activeOnly);
setDisplayOption(val);
}}
>
<SegmentedControl.Option value="all-guides">
All guides
{activeOnly ? "All active" : "All guides"}
</SegmentedControl.Option>
<SegmentedControl.Option value="only-eligible">
Eligible
Expand Down Expand Up @@ -349,7 +356,13 @@ export const V2 = () => {
{/* Collapsible panel to show context data */}
{isContextPanelOpen && (
<Box borderBottom="px">
<GuideContextDetails />
<GuideContextDetails
activeOnly={activeOnly}
onActiveOnlyChange={(nextActiveOnly) => {
maybeClearStaleFocus(displayOption, nextActiveOnly);
setActiveOnly(nextActiveOnly);
}}
/>
</Box>
)}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ export type UncommittedGuide = {
annotation: {
isEligible: false;
isQualified: false;
active: {
status: false;
};
selectable: {
status: undefined;
};
Expand Down Expand Up @@ -407,6 +410,9 @@ const newUncommittedGuide = (key: KnockGuide["key"], orderIndex: number) =>
annotation: {
isEligible: false,
isQualified: false,
active: {
status: false,
},
selectable: {
status: undefined,
},
Expand Down
Loading