Fix organizations page layout + search input display logic
Signed-off-by: Émile Ré <emile@getprobo.com>
This commit is contained in:
@@ -14,6 +14,8 @@ All notable changes to this project will be documented in this file.
|
|||||||
|
|
||||||
- Missing console react-pdf dependency in package.json
|
- Missing console react-pdf dependency in package.json
|
||||||
- On sign out, clear cookie along with the existing session expiration
|
- On sign out, clear cookie along with the existing session expiration
|
||||||
|
- Remove conditional rendering of org search input on console
|
||||||
|
- Fix organizations page layout vertical alignment
|
||||||
|
|
||||||
## [0.116.1] - 2026-01-18
|
## [0.116.1] - 2026-01-18
|
||||||
|
|
||||||
|
|||||||
@@ -107,16 +107,14 @@ export function MembershipsPage(props: {
|
|||||||
{__("Your organizations")}
|
{__("Your organizations")}
|
||||||
</h2>
|
</h2>
|
||||||
)}
|
)}
|
||||||
{memberships.length > 3 && (
|
<div className="w-full">
|
||||||
<div className="w-full">
|
<Input
|
||||||
<Input
|
icon={IconMagnifyingGlass}
|
||||||
icon={IconMagnifyingGlass}
|
placeholder={__("Search organizations...")}
|
||||||
placeholder={__("Search organizations...")}
|
value={search}
|
||||||
value={search}
|
onValueChange={setSearch}
|
||||||
onValueChange={setSearch}
|
/>
|
||||||
/>
|
</div>
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{memberships.length === 0 ? (
|
{memberships.length === 0 ? (
|
||||||
<div className="text-center text-txt-secondary py-4">
|
<div className="text-center text-txt-secondary py-4">
|
||||||
{__("No organizations found")}
|
{__("No organizations found")}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { graphql, usePreloadedQuery, type PreloadedQuery } from "react-relay";
|
import { graphql, usePreloadedQuery, type PreloadedQuery } from "react-relay";
|
||||||
import { Outlet } from "react-router";
|
import { Outlet } from "react-router";
|
||||||
import { CenteredLayout, Layout, Skeleton } from "@probo/ui";
|
import { Layout, Skeleton } from "@probo/ui";
|
||||||
import type { ViewerLayoutQuery } from "/__generated__/iam/ViewerLayoutQuery.graphql";
|
import type { ViewerLayoutQuery } from "/__generated__/iam/ViewerLayoutQuery.graphql";
|
||||||
import { Suspense } from "react";
|
import { Suspense } from "react";
|
||||||
import { ViewerDropdown } from "./_components/ViewerDropdown";
|
import { ViewerDropdown } from "./_components/ViewerDropdown";
|
||||||
@@ -34,9 +34,7 @@ export function ViewerLayout(props: {
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<CenteredLayout>
|
<Outlet />
|
||||||
<Outlet />
|
|
||||||
</CenteredLayout>
|
|
||||||
</Layout>
|
</Layout>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { useQueryLoader } from "react-relay";
|
import { useQueryLoader } from "react-relay";
|
||||||
import { Suspense, useEffect } from "react";
|
import { Suspense, useEffect } from "react";
|
||||||
import { CenteredLayoutSkeleton } from "@probo/ui";
|
|
||||||
import type { ViewerLayoutQuery } from "/__generated__/iam/ViewerLayoutQuery.graphql";
|
import type { ViewerLayoutQuery } from "/__generated__/iam/ViewerLayoutQuery.graphql";
|
||||||
import { ViewerLayout, viewerLayoutQuery } from "./ViewerLayout";
|
import { ViewerLayout, viewerLayoutQuery } from "./ViewerLayout";
|
||||||
import { IAMRelayProvider } from "/providers/IAMRelayProvider";
|
import { IAMRelayProvider } from "/providers/IAMRelayProvider";
|
||||||
|
import { ViewerLayoutLoading } from "./ViewerLayoutLoading";
|
||||||
|
|
||||||
function ViewerLayoutLoader() {
|
function ViewerLayoutLoader() {
|
||||||
const [queryRef, loadQuery] =
|
const [queryRef, loadQuery] =
|
||||||
@@ -14,11 +14,11 @@ function ViewerLayoutLoader() {
|
|||||||
}, [loadQuery]);
|
}, [loadQuery]);
|
||||||
|
|
||||||
if (!queryRef) {
|
if (!queryRef) {
|
||||||
return <CenteredLayoutSkeleton />;
|
return <ViewerLayoutLoading />;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Suspense fallback={<CenteredLayoutSkeleton />}>
|
<Suspense fallback={<ViewerLayoutLoading />}>
|
||||||
<ViewerLayout queryRef={queryRef} />
|
<ViewerLayout queryRef={queryRef} />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import { Layout, Skeleton } from "@probo/ui";
|
||||||
|
import { Outlet } from "react-router";
|
||||||
|
|
||||||
|
export function ViewerLayoutLoading() {
|
||||||
|
return (
|
||||||
|
<Layout
|
||||||
|
headerTrailing={
|
||||||
|
<div className="ml-auto">
|
||||||
|
<Skeleton className="w-32 h-8" />
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Outlet />
|
||||||
|
</Layout>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,8 +1,15 @@
|
|||||||
import { useTranslate } from "@probo/i18n";
|
import { useTranslate } from "@probo/i18n";
|
||||||
import { Button, Card, Field, PageHeader, useToast } from "@probo/ui";
|
import {
|
||||||
|
Button,
|
||||||
|
Card,
|
||||||
|
Field,
|
||||||
|
IconChevronLeft,
|
||||||
|
PageHeader,
|
||||||
|
useToast,
|
||||||
|
} from "@probo/ui";
|
||||||
import { graphql, useMutation } from "react-relay";
|
import { graphql, useMutation } from "react-relay";
|
||||||
import type { FormEventHandler } from "react";
|
import type { FormEventHandler } from "react";
|
||||||
import { useNavigate } from "react-router";
|
import { Link, useLocation, useNavigate } from "react-router";
|
||||||
import { formatError } from "@probo/helpers";
|
import { formatError } from "@probo/helpers";
|
||||||
import type { NewOrganizationPageMutation } from "/__generated__/iam/NewOrganizationPageMutation.graphql";
|
import type { NewOrganizationPageMutation } from "/__generated__/iam/NewOrganizationPageMutation.graphql";
|
||||||
import { IAMRelayProvider } from "/providers/IAMRelayProvider";
|
import { IAMRelayProvider } from "/providers/IAMRelayProvider";
|
||||||
@@ -19,6 +26,7 @@ const createOrganizationMutation = graphql`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
function NewOrganizationPage() {
|
function NewOrganizationPage() {
|
||||||
|
const location = useLocation();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { toast } = useToast();
|
const { toast } = useToast();
|
||||||
const { __ } = useTranslate();
|
const { __ } = useTranslate();
|
||||||
@@ -75,6 +83,13 @@ function NewOrganizationPage() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
|
<Link
|
||||||
|
to={location.state?.from ?? "/"}
|
||||||
|
className="mb-4 inline-flex gap-2 items-center"
|
||||||
|
>
|
||||||
|
<IconChevronLeft size={16} />
|
||||||
|
{__("Back")}
|
||||||
|
</Link>
|
||||||
<PageHeader
|
<PageHeader
|
||||||
title={__("Create Organization")}
|
title={__("Create Organization")}
|
||||||
description={__(
|
description={__(
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import {
|
|||||||
import { Suspense, useCallback, useState } from "react";
|
import { Suspense, useCallback, useState } from "react";
|
||||||
import { useTranslate } from "@probo/i18n";
|
import { useTranslate } from "@probo/i18n";
|
||||||
import type { MembershipsDropdownMenuQuery } from "/__generated__/iam/MembershipsDropdownMenuQuery.graphql";
|
import type { MembershipsDropdownMenuQuery } from "/__generated__/iam/MembershipsDropdownMenuQuery.graphql";
|
||||||
import { Link } from "react-router";
|
import { Link, useLocation } from "react-router";
|
||||||
import type { MembershipsDropdown_organizationFragment$key } from "/__generated__/iam/MembershipsDropdown_organizationFragment.graphql";
|
import type { MembershipsDropdown_organizationFragment$key } from "/__generated__/iam/MembershipsDropdown_organizationFragment.graphql";
|
||||||
import type { MembershipsDropdown_viewerFragment$key } from "/__generated__/iam/MembershipsDropdown_viewerFragment.graphql";
|
import type { MembershipsDropdown_viewerFragment$key } from "/__generated__/iam/MembershipsDropdown_viewerFragment.graphql";
|
||||||
import {
|
import {
|
||||||
@@ -42,6 +42,7 @@ export function MembershipsDropdown(props: {
|
|||||||
}) {
|
}) {
|
||||||
const { organizationFKey, viewerFKey } = props;
|
const { organizationFKey, viewerFKey } = props;
|
||||||
|
|
||||||
|
const location = useLocation();
|
||||||
const { __ } = useTranslate();
|
const { __ } = useTranslate();
|
||||||
const [search, setSearch] = useState("");
|
const [search, setSearch] = useState("");
|
||||||
|
|
||||||
@@ -119,7 +120,7 @@ export function MembershipsDropdown(props: {
|
|||||||
</DropdownItem>
|
</DropdownItem>
|
||||||
)}
|
)}
|
||||||
<DropdownItem asChild>
|
<DropdownItem asChild>
|
||||||
<Link to="/organizations/new">
|
<Link to="/organizations/new" state={{ from: location.pathname }}>
|
||||||
<IconPlusLarge size={16} />
|
<IconPlusLarge size={16} />
|
||||||
{__("Add organization")}
|
{__("Add organization")}
|
||||||
</Link>
|
</Link>
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import {
|
|||||||
redirect,
|
redirect,
|
||||||
useRouteError,
|
useRouteError,
|
||||||
} from "react-router";
|
} from "react-router";
|
||||||
import { CenteredLayoutSkeleton } from "@probo/ui";
|
|
||||||
import { PageSkeleton } from "./components/skeletons/PageSkeleton.tsx";
|
import { PageSkeleton } from "./components/skeletons/PageSkeleton.tsx";
|
||||||
import { riskRoutes } from "./routes/riskRoutes.ts";
|
import { riskRoutes } from "./routes/riskRoutes.ts";
|
||||||
import { measureRoutes } from "./routes/measureRoutes.ts";
|
import { measureRoutes } from "./routes/measureRoutes.ts";
|
||||||
@@ -36,6 +35,8 @@ import {
|
|||||||
} from "@probo/relay";
|
} from "@probo/relay";
|
||||||
import { CurrentUser } from "./providers/CurrentUser.tsx";
|
import { CurrentUser } from "./providers/CurrentUser.tsx";
|
||||||
import { use } from "react";
|
import { use } from "react";
|
||||||
|
import { ViewerLayoutLoading } from "./pages/iam/memberships/ViewerLayoutLoading.tsx";
|
||||||
|
import { CenteredLayout } from "@probo/ui";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Top level error boundary
|
* Top level error boundary
|
||||||
@@ -104,7 +105,7 @@ const routes = [
|
|||||||
{
|
{
|
||||||
path: "/",
|
path: "/",
|
||||||
Component: lazy(() => import("./pages/iam/memberships/ViewerLayoutLoader")),
|
Component: lazy(() => import("./pages/iam/memberships/ViewerLayoutLoader")),
|
||||||
Fallback: CenteredLayoutSkeleton,
|
Fallback: ViewerLayoutLoading,
|
||||||
ErrorBoundary: ErrorBoundary,
|
ErrorBoundary: ErrorBoundary,
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
@@ -114,18 +115,27 @@ const routes = [
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "organizations/new",
|
Component: CenteredLayout,
|
||||||
Component: lazy(
|
children: [
|
||||||
() => import("./pages/iam/organizations/NewOrganizationPage"),
|
{
|
||||||
),
|
path: "organizations/new",
|
||||||
},
|
Component: lazy(
|
||||||
{
|
() => import("./pages/iam/organizations/NewOrganizationPage"),
|
||||||
path: "documents/signing-requests",
|
),
|
||||||
Component: lazy(() => import("./pages/DocumentSigningRequestsPage")),
|
},
|
||||||
},
|
{
|
||||||
{
|
path: "documents/signing-requests",
|
||||||
path: "me/api-keys",
|
Component: lazy(
|
||||||
Component: lazy(() => import("./pages/iam/apiKeys/APIKeysPageLoader")),
|
() => import("./pages/DocumentSigningRequestsPage"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "me/api-keys",
|
||||||
|
Component: lazy(
|
||||||
|
() => import("./pages/iam/apiKeys/APIKeysPageLoader"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user