Skip to content

Commit dcefd7e

Browse files
feat(ui): Workspace CRUD (#261)
* - workspace update name - workspace read team members * - setCurrentWorkspace to update in navigation * - role type fix * - typescript errors * - Minor changes to type - Add methods for members Crud on workspace * - search user query implementation * - update type on Role and related changes * - type error * - language stuff * - updated workspace crud * - updated comment - fixed type * - sort the members * - a single comma can ruin the layout * - minor changes * - revert back * - an actual bug * - using local cache rather than api calls * - fixes and fixes * - remove workspace description * - added minor changes * - Minor refactor * - minor fix * - added a comment * - minor change * - removed flatmap
1 parent f737891 commit dcefd7e

File tree

27 files changed

+614
-190
lines changed

27 files changed

+614
-190
lines changed

ui/src/features/NotFoundPage/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ type Props = {
1010

1111
const NotFoundPage: React.FC<Props> = ({ message }) => {
1212
const t = useT();
13-
const { getMe } = useUser();
14-
const { me } = getMe();
13+
const { useGetMe } = useUser();
14+
const { me } = useGetMe();
1515

1616
return (
1717
<div className="bg-zinc-800 h-[100vh] flex justify-center items-center">

ui/src/features/PageWrapper/WorkspaceId.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ type Props = {
1212
};
1313

1414
const WorkspaceIdWrapper: React.FC<Props> = ({ children }) => {
15-
const [currentWorkspace, setCurrentWorkspace] = useCurrentWorkspace();
15+
const [_, setCurrentWorkspace] = useCurrentWorkspace();
1616

1717
const { workspaceId }: { workspaceId: string } = useParams({
1818
strict: false,
@@ -23,11 +23,10 @@ const WorkspaceIdWrapper: React.FC<Props> = ({ children }) => {
2323

2424
useEffect(() => {
2525
if (!workspace) return;
26-
if (currentWorkspace?.id === workspace.id) return;
2726
setCurrentWorkspace(workspace);
2827

2928
return;
30-
}, [workspace, currentWorkspace, setCurrentWorkspace]);
29+
}, [workspace, setCurrentWorkspace]);
3130

3231
if (isLoading) return <Loading />;
3332

ui/src/features/TopNavigation/components/UserNavigation.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ const UserNavigation: React.FC<Props> = ({
3333
const t = useT();
3434
const [, setDialogType] = useDialogType();
3535
const { logout: handleLogout, user } = useAuth();
36-
const { getMe } = useUser();
37-
const data = getMe().me;
36+
const { useGetMe } = useUser();
37+
const { me } = useGetMe();
3838

3939
const { tosUrl, documentationUrl } = config();
4040

@@ -47,12 +47,12 @@ const UserNavigation: React.FC<Props> = ({
4747
<div className={`flex gap-2 mr-2 ${className}`}>
4848
<Avatar className="h-8 w-8">
4949
<AvatarImage src={user?.picture} />
50-
<AvatarFallback>{data?.name ? data?.name.charAt(0).toUpperCase() : "F"}</AvatarFallback>
50+
<AvatarFallback>{me?.name ? me.name.charAt(0).toUpperCase() : "F"}</AvatarFallback>
5151
</Avatar>
5252
{!iconOnly ? (
5353
<div className="flex items-center gap-2 self-center">
5454
<p className="text-zinc-300 text-sm font-extralight max-w-28 truncate transition-all delay-0 duration-500 hover:max-w-[30vw] hover:delay-500">
55-
{data?.name ? data?.name : "User"}
55+
{me?.name ? me.name : "User"}
5656
</p>
5757
<CaretDown className="w-[12px]" weight="thin" />
5858
</div>

ui/src/features/WorkspaceSettings/components/GeneralSettings.tsx

Lines changed: 41 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,53 @@
11
import { useNavigate } from "@tanstack/react-router";
2-
import { useState } from "react";
2+
import { useEffect, useState } from "react";
33

44
import { Button, Input, Label } from "@flow/components";
55
import { useWorkspace } from "@flow/lib/gql";
66
import { useT } from "@flow/lib/i18n";
77
import { useCurrentWorkspace } from "@flow/stores";
88

9+
type Errors = "delete" | "update";
10+
911
const GeneralSettings: React.FC = () => {
1012
const t = useT();
1113
const [currentWorkspace] = useCurrentWorkspace();
12-
const { deleteWorkspace } = useWorkspace();
14+
const { deleteWorkspace, updateWorkspace } = useWorkspace();
1315
const navigate = useNavigate();
14-
const [showError, setShowError] = useState(false);
16+
const [showError, setShowError] = useState<Errors | undefined>(undefined);
17+
const [workspaceName, setWorkspaceName] = useState(currentWorkspace?.name);
18+
const [loading, setLoading] = useState(false);
1519

1620
const handleDeleteWorkspace = async () => {
17-
setShowError(false);
21+
setLoading(true);
22+
setShowError(undefined);
1823
if (!currentWorkspace) return;
19-
// TODO: this trigger a pop up for confirming
24+
// TODO: this should trigger a pop up for confirming
2025
const { workspaceId } = await deleteWorkspace(currentWorkspace.id);
2126

2227
if (!workspaceId) {
23-
setShowError(true);
28+
setShowError("delete");
2429
return;
2530
}
2631
navigate({ to: "/workspace" });
2732
};
33+
34+
const handleUpdateWorkspace = async () => {
35+
setLoading(true);
36+
setShowError(undefined);
37+
if (!currentWorkspace?.id || !workspaceName) return;
38+
const { workspace } = await updateWorkspace(currentWorkspace?.id, workspaceName);
39+
setLoading(false);
40+
if (!workspace) {
41+
setShowError("update");
42+
return;
43+
}
44+
};
45+
46+
// currentWorkspace can be changed from the navigation
47+
useEffect(() => {
48+
setWorkspaceName(currentWorkspace?.name);
49+
}, [currentWorkspace]);
50+
2851
return (
2952
<div>
3053
<p className="text-lg font-extralight">{t("General Settings")}</p>
@@ -34,29 +57,27 @@ const GeneralSettings: React.FC = () => {
3457
<Input
3558
id="workspace-name"
3659
placeholder={t("Workspace Name")}
37-
readOnly={true}
38-
disabled={true}
39-
value={currentWorkspace?.name}
60+
disabled={currentWorkspace?.personal || loading}
61+
value={workspaceName}
62+
onChange={e => setWorkspaceName(e.target.value)}
4063
/>
4164
</div>
42-
{/* <div className="flex flex-col gap-2">
43-
<Label htmlFor="workspace-description">{t("Workspace Description")}</Label>
44-
<Input
45-
id="workspace-description"
46-
placeholder={t("Workspace Description")}
47-
defaultValue={currentWorkspace?.description}
48-
/>
49-
</div> */}
50-
<Button className="self-end">{t("Save")}</Button>
65+
<Button
66+
className="self-end"
67+
disabled={loading || !workspaceName || currentWorkspace?.personal}
68+
onClick={handleUpdateWorkspace}>
69+
{t("Save")}
70+
</Button>
5171
<Button
5272
variant={"destructive"}
53-
disabled={currentWorkspace?.personal}
73+
disabled={currentWorkspace?.personal || loading}
5474
className="self-end"
5575
onClick={() => handleDeleteWorkspace()}>
5676
{t("Delete Workspace")}
5777
</Button>
5878
<div className={`text-xs text-red-400 self-end ${showError ? "opacity-70" : "opacity-0"}`}>
59-
{t("Failed to delete workspace")}
79+
{showError === "delete" && t("Failed to delete Workspace")}
80+
{showError === "update" && t("Failed to update Workspace")}
6081
</div>
6182
</div>
6283
</div>

ui/src/features/WorkspaceSettings/components/IntegrationsSettings.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { IntegrationMember } from "@flow/types/integration";
1616

1717
type Filter = "all" | Role;
1818

19-
const roles = ["admin", "reader", "writer"];
19+
const roles: Role[] = Object.values(Role);
2020

2121
const IntegrationsSettings: React.FC = () => {
2222
const t = useT();
@@ -26,9 +26,10 @@ const IntegrationsSettings: React.FC = () => {
2626

2727
const filters: { id: Filter; title: string }[] = [
2828
{ id: "all", title: t("All") },
29-
{ id: "admin", title: t("Admin") },
30-
{ id: "reader", title: t("Reader") },
31-
{ id: "writer", title: t("Writer") },
29+
{ id: Role.Owner, title: t("Owner") },
30+
{ id: Role.Reader, title: t("Reader") },
31+
{ id: Role.Reader, title: t("Maintainer") },
32+
{ id: Role.Writer, title: t("Writer") },
3233
];
3334

3435
const integrations: IntegrationMember[] =

0 commit comments

Comments
 (0)