Plug back new org CTA in org dropdown
Signed-off-by: Émile Ré <nemile.re@gmail.com>
This commit is contained in:
@@ -4,8 +4,8 @@ import {
|
|||||||
type PreloadedQuery,
|
type PreloadedQuery,
|
||||||
} from "react-relay";
|
} from "react-relay";
|
||||||
import { organizationLayoutQuery } from "./OrganizationLayoutQuery";
|
import { organizationLayoutQuery } from "./OrganizationLayoutQuery";
|
||||||
import { Outlet } from "react-router";
|
import { Link, Outlet } from "react-router";
|
||||||
import { Layout, Skeleton } from "@probo/ui";
|
import { Badge, Button, IconPeopleAdd, Layout, Skeleton } from "@probo/ui";
|
||||||
import { Sidebar } from "./_components/Sidebar";
|
import { Sidebar } from "./_components/Sidebar";
|
||||||
import { OrganizationDropdown } from "./_components/OrganizationDropdown";
|
import { OrganizationDropdown } from "./_components/OrganizationDropdown";
|
||||||
import { consoleEnvironment } from "/environments";
|
import { consoleEnvironment } from "/environments";
|
||||||
@@ -13,6 +13,7 @@ import type { OrganizationLayoutQuery } from "./__generated__/OrganizationLayout
|
|||||||
import { PermissionsProvider } from "/providers/PermissionsProvider";
|
import { PermissionsProvider } from "/providers/PermissionsProvider";
|
||||||
import { SessionDropdown } from "./_components/SessionDropdown";
|
import { SessionDropdown } from "./_components/SessionDropdown";
|
||||||
import { Suspense } from "react";
|
import { Suspense } from "react";
|
||||||
|
import { useTranslate } from "@probo/i18n";
|
||||||
|
|
||||||
interface OrganizationLayoutProps {
|
interface OrganizationLayoutProps {
|
||||||
queryRef: PreloadedQuery<OrganizationLayoutQuery>;
|
queryRef: PreloadedQuery<OrganizationLayoutQuery>;
|
||||||
@@ -21,7 +22,9 @@ interface OrganizationLayoutProps {
|
|||||||
export default function OrganizationLayout(props: OrganizationLayoutProps) {
|
export default function OrganizationLayout(props: OrganizationLayoutProps) {
|
||||||
const { queryRef } = props;
|
const { queryRef } = props;
|
||||||
|
|
||||||
const data = usePreloadedQuery<OrganizationLayoutQuery>(
|
const { __ } = useTranslate();
|
||||||
|
|
||||||
|
const { organization, viewer } = usePreloadedQuery<OrganizationLayoutQuery>(
|
||||||
organizationLayoutQuery,
|
organizationLayoutQuery,
|
||||||
queryRef,
|
queryRef,
|
||||||
);
|
);
|
||||||
@@ -32,10 +35,25 @@ export default function OrganizationLayout(props: OrganizationLayoutProps) {
|
|||||||
header={
|
header={
|
||||||
<>
|
<>
|
||||||
<div className="mr-auto">
|
<div className="mr-auto">
|
||||||
<OrganizationDropdown fKey={data.organization} />
|
<OrganizationDropdown
|
||||||
|
organizationFKey={organization}
|
||||||
|
viewerFKey={viewer}
|
||||||
|
/>
|
||||||
|
{viewer.pendingInvitations.totalCount > 0 && (
|
||||||
|
<Link to="/" className="relative" title={__("Invitations")}>
|
||||||
|
<Button variant="tertiary" icon={IconPeopleAdd} />
|
||||||
|
<Badge
|
||||||
|
variant="info"
|
||||||
|
size="sm"
|
||||||
|
className="absolute -top-1 -right-1 min-w-[20px] h-5 flex items-center justify-center"
|
||||||
|
>
|
||||||
|
{viewer.pendingInvitations.totalCount}
|
||||||
|
</Badge>
|
||||||
|
</Link>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<Suspense fallback={<Skeleton className="w-32 h-8" />}>
|
<Suspense fallback={<Skeleton className="w-32 h-8" />}>
|
||||||
<SessionDropdown fKey={data.viewer} />
|
<SessionDropdown fKey={viewer} />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,12 +12,13 @@ export const organizationLayoutQuery = graphql`
|
|||||||
query OrganizationLayoutQuery($organizationId: ID!) {
|
query OrganizationLayoutQuery($organizationId: ID!) {
|
||||||
organization: node(id: $organizationId) @required(action: THROW) {
|
organization: node(id: $organizationId) @required(action: THROW) {
|
||||||
... on Organization {
|
... on Organization {
|
||||||
...OrganizationDropdownFragment
|
...OrganizationDropdown_organizationFragment
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
viewer @required(action: THROW) {
|
viewer @required(action: THROW) {
|
||||||
pendingInvitations {
|
...OrganizationDropdown_viewerFragment
|
||||||
totalCount
|
pendingInvitations @required(action: THROW) {
|
||||||
|
totalCount @required(action: THROW)
|
||||||
}
|
}
|
||||||
...SessionDropdownFragment @arguments(organizationId: $organizationId)
|
...SessionDropdownFragment @arguments(organizationId: $organizationId)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* @generated SignedSource<<1d82d885a77675a330799121edb5cb69>>
|
* @generated SignedSource<<09fbc762db2d00eb944a0ef9afe3756d>>
|
||||||
* @lightSyntaxTransform
|
* @lightSyntaxTransform
|
||||||
* @nogrep
|
* @nogrep
|
||||||
*/
|
*/
|
||||||
@@ -15,13 +15,13 @@ export type OrganizationLayoutQuery$variables = {
|
|||||||
};
|
};
|
||||||
export type OrganizationLayoutQuery$data = {
|
export type OrganizationLayoutQuery$data = {
|
||||||
readonly organization: {
|
readonly organization: {
|
||||||
readonly " $fragmentSpreads": FragmentRefs<"OrganizationDropdownFragment">;
|
readonly " $fragmentSpreads": FragmentRefs<"OrganizationDropdown_organizationFragment">;
|
||||||
};
|
};
|
||||||
readonly viewer: {
|
readonly viewer: {
|
||||||
readonly pendingInvitations: {
|
readonly pendingInvitations: {
|
||||||
readonly totalCount: number | null | undefined;
|
readonly totalCount: number;
|
||||||
} | null | undefined;
|
};
|
||||||
readonly " $fragmentSpreads": FragmentRefs<"SessionDropdownFragment">;
|
readonly " $fragmentSpreads": FragmentRefs<"OrganizationDropdown_viewerFragment" | "SessionDropdownFragment">;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
export type OrganizationLayoutQuery = {
|
export type OrganizationLayoutQuery = {
|
||||||
@@ -47,19 +47,8 @@ v1 = [
|
|||||||
v2 = {
|
v2 = {
|
||||||
"alias": null,
|
"alias": null,
|
||||||
"args": null,
|
"args": null,
|
||||||
"concreteType": "InvitationConnection",
|
"kind": "ScalarField",
|
||||||
"kind": "LinkedField",
|
"name": "totalCount",
|
||||||
"name": "pendingInvitations",
|
|
||||||
"plural": false,
|
|
||||||
"selections": [
|
|
||||||
{
|
|
||||||
"alias": null,
|
|
||||||
"args": null,
|
|
||||||
"kind": "ScalarField",
|
|
||||||
"name": "totalCount",
|
|
||||||
"storageKey": null
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"storageKey": null
|
"storageKey": null
|
||||||
},
|
},
|
||||||
v3 = [
|
v3 = [
|
||||||
@@ -99,7 +88,7 @@ return {
|
|||||||
{
|
{
|
||||||
"args": null,
|
"args": null,
|
||||||
"kind": "FragmentSpread",
|
"kind": "FragmentSpread",
|
||||||
"name": "OrganizationDropdownFragment"
|
"name": "OrganizationDropdown_organizationFragment"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"type": "Organization",
|
"type": "Organization",
|
||||||
@@ -120,7 +109,31 @@ return {
|
|||||||
"name": "viewer",
|
"name": "viewer",
|
||||||
"plural": false,
|
"plural": false,
|
||||||
"selections": [
|
"selections": [
|
||||||
(v2/*: any*/),
|
{
|
||||||
|
"args": null,
|
||||||
|
"kind": "FragmentSpread",
|
||||||
|
"name": "OrganizationDropdown_viewerFragment"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": "RequiredField",
|
||||||
|
"field": {
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"concreteType": "InvitationConnection",
|
||||||
|
"kind": "LinkedField",
|
||||||
|
"name": "pendingInvitations",
|
||||||
|
"plural": false,
|
||||||
|
"selections": [
|
||||||
|
{
|
||||||
|
"kind": "RequiredField",
|
||||||
|
"field": (v2/*: any*/),
|
||||||
|
"action": "THROW"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
|
"action": "THROW"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"args": (v3/*: any*/),
|
"args": (v3/*: any*/),
|
||||||
"kind": "FragmentSpread",
|
"kind": "FragmentSpread",
|
||||||
@@ -182,7 +195,18 @@ return {
|
|||||||
"name": "viewer",
|
"name": "viewer",
|
||||||
"plural": false,
|
"plural": false,
|
||||||
"selections": [
|
"selections": [
|
||||||
(v2/*: any*/),
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"concreteType": "InvitationConnection",
|
||||||
|
"kind": "LinkedField",
|
||||||
|
"name": "pendingInvitations",
|
||||||
|
"plural": false,
|
||||||
|
"selections": [
|
||||||
|
(v2/*: any*/)
|
||||||
|
],
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"alias": null,
|
"alias": null,
|
||||||
"args": null,
|
"args": null,
|
||||||
@@ -223,16 +247,16 @@ return {
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"params": {
|
"params": {
|
||||||
"cacheID": "0ebb386f89d19888f18a05c8dc573895",
|
"cacheID": "ca7f41668eb74024237351d0e076819e",
|
||||||
"id": null,
|
"id": null,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"name": "OrganizationLayoutQuery",
|
"name": "OrganizationLayoutQuery",
|
||||||
"operationKind": "query",
|
"operationKind": "query",
|
||||||
"text": "query OrganizationLayoutQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n ... on Organization {\n ...OrganizationDropdownFragment\n }\n id\n }\n viewer {\n pendingInvitations {\n totalCount\n }\n ...SessionDropdownFragment_4xMPKw\n id\n }\n}\n\nfragment OrganizationDropdownFragment on Organization {\n name\n}\n\nfragment SessionDropdownFragment_4xMPKw on Identity {\n email\n profileFor(organizationId: $organizationId) {\n firstName\n lastName\n id\n }\n}\n"
|
"text": "query OrganizationLayoutQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n ... on Organization {\n ...OrganizationDropdown_organizationFragment\n }\n id\n }\n viewer {\n ...OrganizationDropdown_viewerFragment\n pendingInvitations {\n totalCount\n }\n ...SessionDropdownFragment_4xMPKw\n id\n }\n}\n\nfragment OrganizationDropdown_organizationFragment on Organization {\n name\n}\n\nfragment OrganizationDropdown_viewerFragment on Identity {\n pendingInvitations {\n totalCount\n }\n}\n\nfragment SessionDropdownFragment_4xMPKw on Identity {\n email\n profileFor(organizationId: $organizationId) {\n firstName\n lastName\n id\n }\n}\n"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
(node as any).hash = "d3d91888eabb36cc450ca585757b21c7";
|
(node as any).hash = "81b8eb0af21d649268e30c80d16226de";
|
||||||
|
|
||||||
export default node;
|
export default node;
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
import { useFragment, useQueryLoader } from "react-relay";
|
import { useFragment, useQueryLoader } from "react-relay";
|
||||||
import { graphql } from "relay-runtime";
|
import { graphql } from "relay-runtime";
|
||||||
import type { OrganizationDropdownFragment$key } from "./__generated__/OrganizationDropdownFragment.graphql";
|
|
||||||
import {
|
import {
|
||||||
|
Badge,
|
||||||
Button,
|
Button,
|
||||||
Dropdown,
|
Dropdown,
|
||||||
|
DropdownItem,
|
||||||
DropdownSeparator,
|
DropdownSeparator,
|
||||||
IconChevronGrabberVertical,
|
IconChevronGrabberVertical,
|
||||||
IconMagnifyingGlass,
|
IconMagnifyingGlass,
|
||||||
|
IconPeopleAdd,
|
||||||
|
IconPlusLarge,
|
||||||
Input,
|
Input,
|
||||||
} from "@probo/ui";
|
} from "@probo/ui";
|
||||||
import { Suspense, useCallback, useState } from "react";
|
import { Suspense, useCallback, useState } from "react";
|
||||||
@@ -16,22 +19,43 @@ import {
|
|||||||
organizationDropdownMenuQuery,
|
organizationDropdownMenuQuery,
|
||||||
} from "./OrganizationDropdownMenu";
|
} from "./OrganizationDropdownMenu";
|
||||||
import type { OrganizationDropdownMenuQuery } from "./__generated__/OrganizationDropdownMenuQuery.graphql";
|
import type { OrganizationDropdownMenuQuery } from "./__generated__/OrganizationDropdownMenuQuery.graphql";
|
||||||
|
import { Link } from "react-router";
|
||||||
|
import type { OrganizationDropdown_organizationFragment$key } from "./__generated__/OrganizationDropdown_organizationFragment.graphql";
|
||||||
|
import type { OrganizationDropdown_viewerFragment$key } from "./__generated__/OrganizationDropdown_viewerFragment.graphql";
|
||||||
|
|
||||||
const fragment = graphql`
|
const organizationFragment = graphql`
|
||||||
fragment OrganizationDropdownFragment on Organization {
|
fragment OrganizationDropdown_organizationFragment on Organization {
|
||||||
name
|
name
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
const viewerFragment = graphql`
|
||||||
|
fragment OrganizationDropdown_viewerFragment on Identity {
|
||||||
|
pendingInvitations @required(action: THROW) {
|
||||||
|
totalCount @required(action: THROW)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
export function OrganizationDropdown(props: {
|
export function OrganizationDropdown(props: {
|
||||||
fKey: OrganizationDropdownFragment$key;
|
organizationFKey: OrganizationDropdown_organizationFragment$key;
|
||||||
|
viewerFKey: OrganizationDropdown_viewerFragment$key;
|
||||||
}) {
|
}) {
|
||||||
const { fKey } = props;
|
const { organizationFKey, viewerFKey } = props;
|
||||||
|
|
||||||
const { __ } = useTranslate();
|
const { __ } = useTranslate();
|
||||||
const [search, setSearch] = useState("");
|
const [search, setSearch] = useState("");
|
||||||
|
|
||||||
const currentOrganization = useFragment(fragment, fKey);
|
const currentOrganization =
|
||||||
|
useFragment<OrganizationDropdown_organizationFragment$key>(
|
||||||
|
organizationFragment,
|
||||||
|
organizationFKey,
|
||||||
|
);
|
||||||
|
const {
|
||||||
|
pendingInvitations: { totalCount: pendingInvitationCount },
|
||||||
|
} = useFragment<OrganizationDropdown_viewerFragment$key>(
|
||||||
|
viewerFragment,
|
||||||
|
viewerFKey,
|
||||||
|
);
|
||||||
const [queryRef, loadQuery] = useQueryLoader<OrganizationDropdownMenuQuery>(
|
const [queryRef, loadQuery] = useQueryLoader<OrganizationDropdownMenuQuery>(
|
||||||
organizationDropdownMenuQuery,
|
organizationDropdownMenuQuery,
|
||||||
);
|
);
|
||||||
@@ -83,6 +107,23 @@ export function OrganizationDropdown(props: {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<DropdownSeparator />
|
<DropdownSeparator />
|
||||||
|
{pendingInvitationCount > 0 && (
|
||||||
|
<DropdownItem asChild>
|
||||||
|
<Link to="/">
|
||||||
|
<IconPeopleAdd size={16} />
|
||||||
|
<span className="flex-1">{__("Invitations")}</span>
|
||||||
|
<Badge variant="info" size="sm">
|
||||||
|
{pendingInvitationCount}
|
||||||
|
</Badge>
|
||||||
|
</Link>
|
||||||
|
</DropdownItem>
|
||||||
|
)}
|
||||||
|
<DropdownItem asChild>
|
||||||
|
<Link to="/organizations/new">
|
||||||
|
<IconPlusLarge size={16} />
|
||||||
|
{__("Add organization")}
|
||||||
|
</Link>
|
||||||
|
</DropdownItem>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* @generated SignedSource<<06f02e43b64c316083067f5b3978a08a>>
|
* @generated SignedSource<<1d2465517ea2dcfa99fb3dd8757fe980>>
|
||||||
* @lightSyntaxTransform
|
* @lightSyntaxTransform
|
||||||
* @nogrep
|
* @nogrep
|
||||||
*/
|
*/
|
||||||
@@ -10,20 +10,20 @@
|
|||||||
|
|
||||||
import { ReaderFragment } from 'relay-runtime';
|
import { ReaderFragment } from 'relay-runtime';
|
||||||
import { FragmentRefs } from "relay-runtime";
|
import { FragmentRefs } from "relay-runtime";
|
||||||
export type OrganizationDropdownFragment$data = {
|
export type OrganizationDropdown_organizationFragment$data = {
|
||||||
readonly name: string;
|
readonly name: string;
|
||||||
readonly " $fragmentType": "OrganizationDropdownFragment";
|
readonly " $fragmentType": "OrganizationDropdown_organizationFragment";
|
||||||
};
|
};
|
||||||
export type OrganizationDropdownFragment$key = {
|
export type OrganizationDropdown_organizationFragment$key = {
|
||||||
readonly " $data"?: OrganizationDropdownFragment$data;
|
readonly " $data"?: OrganizationDropdown_organizationFragment$data;
|
||||||
readonly " $fragmentSpreads": FragmentRefs<"OrganizationDropdownFragment">;
|
readonly " $fragmentSpreads": FragmentRefs<"OrganizationDropdown_organizationFragment">;
|
||||||
};
|
};
|
||||||
|
|
||||||
const node: ReaderFragment = {
|
const node: ReaderFragment = {
|
||||||
"argumentDefinitions": [],
|
"argumentDefinitions": [],
|
||||||
"kind": "Fragment",
|
"kind": "Fragment",
|
||||||
"metadata": null,
|
"metadata": null,
|
||||||
"name": "OrganizationDropdownFragment",
|
"name": "OrganizationDropdown_organizationFragment",
|
||||||
"selections": [
|
"selections": [
|
||||||
{
|
{
|
||||||
"alias": null,
|
"alias": null,
|
||||||
@@ -37,6 +37,6 @@ const node: ReaderFragment = {
|
|||||||
"abstractKey": null
|
"abstractKey": null
|
||||||
};
|
};
|
||||||
|
|
||||||
(node as any).hash = "9f19581f86736e6345912284668a8f25";
|
(node as any).hash = "8e6d0c702f821670315b5bde55e2556a";
|
||||||
|
|
||||||
export default node;
|
export default node;
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
/**
|
||||||
|
* @generated SignedSource<<d4b9efa7b9092ceb3f995507108a68e3>>
|
||||||
|
* @lightSyntaxTransform
|
||||||
|
* @nogrep
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
// @ts-nocheck
|
||||||
|
|
||||||
|
import { ReaderFragment } from 'relay-runtime';
|
||||||
|
import { FragmentRefs } from "relay-runtime";
|
||||||
|
export type OrganizationDropdown_viewerFragment$data = {
|
||||||
|
readonly pendingInvitations: {
|
||||||
|
readonly totalCount: number;
|
||||||
|
};
|
||||||
|
readonly " $fragmentType": "OrganizationDropdown_viewerFragment";
|
||||||
|
};
|
||||||
|
export type OrganizationDropdown_viewerFragment$key = {
|
||||||
|
readonly " $data"?: OrganizationDropdown_viewerFragment$data;
|
||||||
|
readonly " $fragmentSpreads": FragmentRefs<"OrganizationDropdown_viewerFragment">;
|
||||||
|
};
|
||||||
|
|
||||||
|
const node: ReaderFragment = {
|
||||||
|
"argumentDefinitions": [],
|
||||||
|
"kind": "Fragment",
|
||||||
|
"metadata": null,
|
||||||
|
"name": "OrganizationDropdown_viewerFragment",
|
||||||
|
"selections": [
|
||||||
|
{
|
||||||
|
"kind": "RequiredField",
|
||||||
|
"field": {
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"concreteType": "InvitationConnection",
|
||||||
|
"kind": "LinkedField",
|
||||||
|
"name": "pendingInvitations",
|
||||||
|
"plural": false,
|
||||||
|
"selections": [
|
||||||
|
{
|
||||||
|
"kind": "RequiredField",
|
||||||
|
"field": {
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "totalCount",
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
|
"action": "THROW"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
|
"action": "THROW"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"type": "Identity",
|
||||||
|
"abstractKey": null
|
||||||
|
};
|
||||||
|
|
||||||
|
(node as any).hash = "ce947f812c95b74e9f250b8d5821ebb0";
|
||||||
|
|
||||||
|
export default node;
|
||||||
Reference in New Issue
Block a user