Skip to content

Commit 85d7826

Browse files
committed
feat: improve playbooks menu
Fixes #2334
1 parent ff169ac commit 85d7826

File tree

2 files changed

+68
-170
lines changed

2 files changed

+68
-170
lines changed
Lines changed: 68 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,9 @@
11
import { AuthorizationAccessCheck } from "@flanksource-ui/components/Permissions/AuthorizationAccessCheck";
2+
import CollapsiblePanel from "@flanksource-ui/ui/CollapsiblePanel/CollapsiblePanel";
23
import { Icon } from "@flanksource-ui/ui/Icons/Icon";
3-
import {
4-
Menu,
5-
MenuButton,
6-
MenuItem,
7-
MenuItems,
8-
Transition
9-
} from "@headlessui/react";
4+
import { Popover, PopoverButton, PopoverPanel } from "@headlessui/react";
105
import { ChevronDownIcon } from "@heroicons/react/solid";
11-
import { Fragment, useState } from "react";
6+
import { useMemo, useState } from "react";
127
import { useGetPlaybooksToRun } from "../../../../api/query-hooks/playbooks";
138
import { RunnablePlaybook } from "../../../../api/types/playbooks";
149
import PlaybookSpecIcon from "../../Settings/PlaybookSpecIcon";
@@ -43,47 +38,79 @@ export default function PlaybooksDropdownMenu({
4338
config_id
4439
});
4540

41+
const playbooksGroupedByCategory = useMemo(
42+
() =>
43+
playbooks?.reduce(
44+
(acc, playbook) => {
45+
const category = playbook.spec?.category || "Uncategorized";
46+
if (!acc[category]) {
47+
acc[category] = [];
48+
}
49+
acc[category].push(playbook);
50+
return acc;
51+
},
52+
{} as Record<
53+
string,
54+
(RunnablePlaybook & {
55+
spec: any;
56+
})[]
57+
>
58+
),
59+
[playbooks]
60+
);
61+
4662
if (error || playbooks?.length === 0 || isLoading) {
4763
return null;
4864
}
4965

5066
return (
5167
<AuthorizationAccessCheck resource={"playbook_runs"} action={"write"}>
52-
<div className="my-2 text-right">
53-
<Menu as="div" className="relative inline-block text-left">
54-
<MenuButton className="btn-white px-2 py-1">
68+
<>
69+
<Popover className="group">
70+
<PopoverButton className="btn-white px-2 py-1">
5571
<Icon name="playbook" className="mr-2 mt-0.5 h-5 w-5" />
5672
Playbooks
57-
<ChevronDownIcon
58-
className="-mr-1 ml-2 h-5 w-5 text-gray-400"
59-
aria-hidden="true"
60-
/>
61-
</MenuButton>
62-
63-
{/* @ts-ignore */}
64-
<Transition
65-
as={Fragment as any}
66-
enter="transition ease-out duration-100"
67-
enterFrom="transform opacity-0 scale-95"
68-
enterTo="transform opacity-100 scale-100"
69-
leave="transition ease-in duration-75"
70-
leaveFrom="transform opacity-100 scale-100"
71-
leaveTo="transform opacity-0 scale-95"
73+
<ChevronDownIcon className="size-5 group-data-[open]:rotate-180" />
74+
</PopoverButton>
75+
<PopoverPanel
76+
portal
77+
className="menu-items absolute right-0 mt-2 w-56 origin-top-right divide-y divide-gray-100 rounded-md bg-white shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none"
78+
anchor="bottom start"
7279
>
73-
<MenuItems portal className="menu-items" anchor="bottom start">
74-
{playbooks?.map((playbook) => (
75-
<MenuItem
76-
as="button"
77-
className="menu-item w-full"
78-
onClick={() => setSelectedPlaybookSpec(playbook)}
79-
key={playbook.id}
80-
>
81-
<PlaybookSpecIcon playbook={playbook} showLabel showTag />
82-
</MenuItem>
83-
))}
84-
</MenuItems>
85-
</Transition>
86-
</Menu>
80+
{playbooksGroupedByCategory && (
81+
<>
82+
{Object.entries(playbooksGroupedByCategory).map(
83+
([category, playbooks]) => (
84+
<CollapsiblePanel
85+
key={category}
86+
Header={
87+
<div className="flex flex-row items-center gap-2 text-sm text-gray-600">
88+
{category}
89+
</div>
90+
}
91+
iconClassName="h-4 w-4"
92+
isCollapsed
93+
>
94+
<div className={`flex flex-col`}>
95+
{playbooks.map((playbook) => (
96+
<div
97+
key={playbook.id}
98+
onClick={() => {
99+
setSelectedPlaybookSpec(playbook);
100+
}}
101+
className={`flex cursor-pointer flex-col justify-between gap-1 px-4 py-2 text-sm`}
102+
>
103+
<PlaybookSpecIcon playbook={playbook} showLabel />
104+
</div>
105+
))}
106+
</div>
107+
</CollapsiblePanel>
108+
)
109+
)}
110+
</>
111+
)}
112+
</PopoverPanel>
113+
</Popover>
87114
{selectedPlaybookSpec && (
88115
<SubmitPlaybookRunForm
89116
componentId={component_id}
@@ -96,7 +123,7 @@ export default function PlaybooksDropdownMenu({
96123
playbook={selectedPlaybookSpec}
97124
/>
98125
)}
99-
</div>
126+
</>
100127
</AuthorizationAccessCheck>
101128
);
102129
}

src/components/Playbooks/Runs/Submit/__tests__/SelectPlaybookToRun.unit.test.tsx

Lines changed: 0 additions & 129 deletions
This file was deleted.

0 commit comments

Comments
 (0)