[WEB-5603] feat: enhance workspace settings layout and members page (#8266)

* feat: enhance workspace settings layout and members page with new components

* refactor: update workspace settings layout and members page to use default exports

* refactor: settings layout import changes

* refactor: simplify workspaceSlug usage in settings layout
This commit is contained in:
b-saikrishnakanth 2025-12-09 21:04:33 +05:30 committed by GitHub
parent 7caa1bb482
commit f70384bff7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 49 additions and 17 deletions

View file

@ -1,26 +1,32 @@
import { observer } from "mobx-react"; import { observer } from "mobx-react";
import { usePathname } from "next/navigation"; import { usePathname } from "next/navigation";
import { Outlet } from "react-router"; import { Outlet } from "react-router";
// constants
import { WORKSPACE_SETTINGS_ACCESS } from "@plane/constants";
import type { EUserWorkspaceRoles } from "@plane/types";
// components // components
import { NotAuthorizedView } from "@/components/auth-screens/not-authorized-view"; import { NotAuthorizedView } from "@/components/auth-screens/not-authorized-view";
import { getWorkspaceActivePath, pathnameToAccessKey } from "@/components/settings/helper"; import { getWorkspaceActivePath, pathnameToAccessKey } from "@/components/settings/helper";
import { SettingsMobileNav } from "@/components/settings/mobile"; import { SettingsMobileNav } from "@/components/settings/mobile";
// plane imports
import { WORKSPACE_SETTINGS_ACCESS } from "@plane/constants";
import type { EUserWorkspaceRoles } from "@plane/types";
// plane web components
import { WorkspaceSettingsRightSidebar } from "@/plane-web/components/workspace/right-sidebar";
// hooks // hooks
import { useUserPermissions } from "@/hooks/store/user"; import { useUserPermissions } from "@/hooks/store/user";
// local components // local components
import { WorkspaceSettingsSidebar } from "./sidebar"; import { WorkspaceSettingsSidebar } from "./sidebar";
function WorkspaceSettingLayout() { import type { Route } from "./+types/layout";
const WorkspaceSettingLayout = observer(function WorkspaceSettingLayout({ params }: Route.ComponentProps) {
// router
const { workspaceSlug } = params;
// store hooks // store hooks
const { workspaceUserInfo, getWorkspaceRoleByWorkspaceSlug } = useUserPermissions(); const { workspaceUserInfo, getWorkspaceRoleByWorkspaceSlug } = useUserPermissions();
// next hooks // next hooks
const pathname = usePathname(); const pathname = usePathname();
// derived values // derived values
const { workspaceSlug, accessKey } = pathnameToAccessKey(pathname); const { accessKey } = pathnameToAccessKey(pathname);
const userWorkspaceRole = getWorkspaceRoleByWorkspaceSlug(workspaceSlug.toString()); const userWorkspaceRole = getWorkspaceRoleByWorkspaceSlug(workspaceSlug);
let isAuthorized: boolean | string = false; let isAuthorized: boolean | string = false;
if (pathname && workspaceSlug && userWorkspaceRole) { if (pathname && workspaceSlug && userWorkspaceRole) {
@ -42,11 +48,12 @@ function WorkspaceSettingLayout() {
<div className="w-full h-full overflow-y-scroll md:pt-page-y"> <div className="w-full h-full overflow-y-scroll md:pt-page-y">
<Outlet /> <Outlet />
</div> </div>
<WorkspaceSettingsRightSidebar workspaceSlug={workspaceSlug} />
</div> </div>
)} )}
</div> </div>
</> </>
); );
} });
export default observer(WorkspaceSettingLayout); export default WorkspaceSettingLayout;

View file

@ -28,10 +28,10 @@ import { useWorkspace } from "@/hooks/store/use-workspace";
import { useUserPermissions } from "@/hooks/store/user"; import { useUserPermissions } from "@/hooks/store/user";
// plane web components // plane web components
import { BillingActionsButton } from "@/plane-web/components/workspace/billing/billing-actions-button"; import { BillingActionsButton } from "@/plane-web/components/workspace/billing/billing-actions-button";
import { SendWorkspaceInvitationModal } from "@/plane-web/components/workspace/members/invite-modal"; import { SendWorkspaceInvitationModal, MembersActivityButton } from "@/plane-web/components/workspace/members";
import type { Route } from "./+types/page"; import type { Route } from "./+types/page";
function WorkspaceMembersSettingsPage({ params }: Route.ComponentProps) { const WorkspaceMembersSettingsPage = observer(function WorkspaceMembersSettingsPage({ params }: Route.ComponentProps) {
// states // states
const [inviteModal, setInviteModal] = useState(false); const [inviteModal, setInviteModal] = useState(false);
const [searchQuery, setSearchQuery] = useState<string>(""); const [searchQuery, setSearchQuery] = useState<string>("");
@ -70,23 +70,27 @@ function WorkspaceMembersSettingsPage({ params }: Route.ComponentProps) {
title: "Success!", title: "Success!",
message: t("workspace_settings.settings.members.invitations_sent_successfully"), message: t("workspace_settings.settings.members.invitations_sent_successfully"),
}); });
// eslint-disable-next-line @typescript-eslint/no-explicit-any } catch (error: unknown) {
} catch (err: any) { let message = undefined;
if (error instanceof Error) {
const err = error as Error & { error?: string };
message = err.error;
}
captureError({ captureError({
eventName: MEMBER_TRACKER_EVENTS.invite, eventName: MEMBER_TRACKER_EVENTS.invite,
payload: { payload: {
emails: data.emails.map((email) => email.email), emails: data.emails.map((email) => email.email),
}, },
error: err, error: error as Error,
}); });
setToast({ setToast({
type: TOAST_TYPE.ERROR, type: TOAST_TYPE.ERROR,
title: "Error!", title: "Error!",
message: `${err.error ?? t("something_went_wrong_please_try_again")}`, message: `${message ?? t("something_went_wrong_please_try_again")}`,
}); });
throw err; throw error;
} }
}; };
@ -137,6 +141,7 @@ function WorkspaceMembersSettingsPage({ params }: Route.ComponentProps) {
className="w-full max-w-[234px] border-none bg-transparent text-sm outline-none placeholder:text-custom-text-400" className="w-full max-w-[234px] border-none bg-transparent text-sm outline-none placeholder:text-custom-text-400"
placeholder={`${t("search")}...`} placeholder={`${t("search")}...`}
value={searchQuery} value={searchQuery}
// eslint-disable-next-line jsx-a11y/no-autofocus
autoFocus autoFocus
onChange={(e) => setSearchQuery(e.target.value)} onChange={(e) => setSearchQuery(e.target.value)}
/> />
@ -146,6 +151,7 @@ function WorkspaceMembersSettingsPage({ params }: Route.ComponentProps) {
handleUpdate={handleRoleFilterUpdate} handleUpdate={handleRoleFilterUpdate}
memberType="workspace" memberType="workspace"
/> />
<MembersActivityButton workspaceSlug={workspaceSlug} />
{canPerformWorkspaceAdminActions && ( {canPerformWorkspaceAdminActions && (
<Button <Button
variant="primary" variant="primary"
@ -163,6 +169,6 @@ function WorkspaceMembersSettingsPage({ params }: Route.ComponentProps) {
</section> </section>
</SettingsContentWrapper> </SettingsContentWrapper>
); );
} });
export default observer(WorkspaceMembersSettingsPage); export default WorkspaceMembersSettingsPage;

View file

@ -0,0 +1,2 @@
export * from "./invite-modal";
export * from "./members-activity-button";

View file

@ -0,0 +1,6 @@
import { observer } from "mobx-react";
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export const MembersActivityButton = observer(function MembersActivityButton(props: { workspaceSlug: string }) {
return <></>;
});

View file

@ -0,0 +1 @@
export * from "./root";

View file

@ -0,0 +1,10 @@
import { observer } from "mobx-react";
type TWorkspaceSettingsRightSidebarProps = { workspaceSlug: string };
export const WorkspaceSettingsRightSidebar = observer(function WorkspaceSettingsRightSidebar(
// eslint-disable-next-line @typescript-eslint/no-unused-vars
props: TWorkspaceSettingsRightSidebarProps
) {
return <></>;
});