Skip to content

Commit b683d56

Browse files
feat: quick "go to settings" for workspace selector (#213)
* feat: quick "go to settings" for workspace selector * fix: failing tests
1 parent 8894ed5 commit b683d56

File tree

2 files changed

+39
-9
lines changed

2 files changed

+39
-9
lines changed

src/features/workspace/components/workspace-name.tsx

+12-4
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
} from "@stacklok/ui-kit";
1111
import { twMerge } from "tailwind-merge";
1212
import { useMutationCreateWorkspace } from "../hooks/use-mutation-create-workspace";
13-
import { FormEvent, useState } from "react";
13+
import { FormEvent, useEffect, useState } from "react";
1414
import { useNavigate } from "react-router-dom";
1515

1616
export function WorkspaceName({
@@ -23,10 +23,17 @@ export function WorkspaceName({
2323
isArchived: boolean | undefined;
2424
}) {
2525
const navigate = useNavigate();
26-
const [name, setName] = useState(workspaceName);
27-
const { mutateAsync, isPending, error } = useMutationCreateWorkspace();
26+
const { mutateAsync, isPending, error, reset } = useMutationCreateWorkspace();
2827
const errorMsg = error?.detail ? `${error?.detail}` : "";
2928

29+
const [name, setName] = useState(() => workspaceName);
30+
// NOTE: When navigating from one settings page to another, this value is not
31+
// updated, hence the synchronization effect
32+
useEffect(() => {
33+
setName(workspaceName);
34+
reset();
35+
}, [reset, workspaceName]);
36+
3037
const handleSubmit = (e: FormEvent<HTMLFormElement>) => {
3138
e.preventDefault();
3239
mutateAsync(
@@ -38,13 +45,14 @@ export function WorkspaceName({
3845
};
3946

4047
return (
41-
<Form onSubmit={handleSubmit} validationBehavior="aria">
48+
<Form onSubmit={handleSubmit} validationBehavior="aria" key={workspaceName}>
4249
<Card
4350
className={twMerge(className, "shrink-0")}
4451
data-testid="workspace-name"
4552
>
4653
<CardBody>
4754
<TextField
55+
key={workspaceName}
4856
aria-label="Workspace name"
4957
value={name}
5058
name="Workspace name"

src/features/workspace/components/workspaces-selection.tsx

+27-5
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ import { useState } from "react";
1616
import { useMutationActivateWorkspace } from "../hooks/use-mutation-activate-workspace";
1717
import clsx from "clsx";
1818
import { useActiveWorkspaceName } from "../hooks/use-active-workspace-name";
19+
import { hrefs } from "@/lib/hrefs";
20+
import { twMerge } from "tailwind-merge";
1921

2022
export function WorkspacesSelection() {
2123
const queryClient = useQueryClient();
@@ -46,7 +48,7 @@ export function WorkspacesSelection() {
4648
<ChevronDown />
4749
</Button>
4850

49-
<Popover className="w-1/4 p-4" placement="bottom left">
51+
<Popover className="w-[32rem] p-3" placement="bottom left">
5052
<div>
5153
<div>
5254
<SearchField
@@ -65,7 +67,7 @@ export function WorkspacesSelection() {
6567
onAction={(v) => {
6668
handleWorkspaceClick(v?.toString());
6769
}}
68-
className="py-2 pt-3 max-h-80 overflow-auto"
70+
className="-mx-1 my-2 max-h-80 overflow-auto"
6971
renderEmptyState={() => (
7072
<p className="text-center">No workspaces found</p>
7173
)}
@@ -74,16 +76,36 @@ export function WorkspacesSelection() {
7476
<ListBoxItem
7577
id={item.name}
7678
key={item.name}
79+
textValue={item.name}
7780
data-is-selected={item.name === activeWorkspaceName}
7881
className={clsx(
79-
"cursor-pointer py-2 m-1 text-base hover:bg-gray-300",
82+
"grid grid-cols-[auto_1.5rem] group/selector cursor-pointer py-2 m-1 text-base hover:bg-gray-200 rounded-sm",
8083
{
8184
"!bg-gray-900 hover:bg-gray-900 !text-gray-25 hover:!text-gray-25":
8285
item.is_active,
8386
},
8487
)}
8588
>
86-
{item.name}
89+
<span className="block truncate">{item.name}</span>
90+
91+
<LinkButton
92+
href={hrefs.workspaces.edit(item.name)}
93+
onPress={() => setIsOpen(false)}
94+
isIcon
95+
variant="tertiary"
96+
className={twMerge(
97+
"ml-auto size-6 group-hover/selector:opacity-100 opacity-0 transition-opacity",
98+
item.is_active
99+
? "hover:bg-gray-800 pressed:bg-gray-700"
100+
: "hover:bg-gray-50 hover:text-primary",
101+
)}
102+
>
103+
<Settings
104+
className={twMerge(
105+
item.is_active ? "text-gray-25" : "text-secondary",
106+
)}
107+
/>
108+
</LinkButton>
87109
</ListBoxItem>
88110
)}
89111
</ListBox>
@@ -92,7 +114,7 @@ export function WorkspacesSelection() {
92114
href="/workspaces"
93115
onPress={() => setIsOpen(false)}
94116
variant="tertiary"
95-
className="text-secondary h-8 pl-2 gap-2 flex mt-2 justify-start"
117+
className="text-secondary h-10 pl-2 gap-2 flex mt-2 justify-start"
96118
>
97119
<Settings />
98120
Manage Workspaces

0 commit comments

Comments
 (0)