Fix employee layout has no sidebar

Signed-off-by: Émile Ré <nemile.re@gmail.com>
This commit is contained in:
Émile Ré
2026-01-02 14:46:31 +01:00
committed by Bryan Frimin
parent e4a1e75deb
commit 5032eac061
6 changed files with 415 additions and 347 deletions

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<698ad015edeb94e58ec661b6118dca4b>> * @generated SignedSource<<5020a4587a487d695572eb77c5e9a959>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -12,6 +12,7 @@ import { ConcreteRequest } from 'relay-runtime';
import { FragmentRefs } from "relay-runtime"; import { FragmentRefs } from "relay-runtime";
export type MembershipRole = "ADMIN" | "AUDITOR" | "EMPLOYEE" | "OWNER" | "VIEWER"; export type MembershipRole = "ADMIN" | "AUDITOR" | "EMPLOYEE" | "OWNER" | "VIEWER";
export type MembershipLayoutQuery$variables = { export type MembershipLayoutQuery$variables = {
hideSidebar: boolean;
organizationId: string; organizationId: string;
}; };
export type MembershipLayoutQuery$data = { export type MembershipLayoutQuery$data = {
@@ -39,42 +40,45 @@ export type MembershipLayoutQuery = {
}; };
const node: ConcreteRequest = (function(){ const node: ConcreteRequest = (function(){
var v0 = [ var v0 = {
{ "defaultValue": null,
"kind": "LocalArgument",
"name": "hideSidebar"
},
v1 = {
"defaultValue": null, "defaultValue": null,
"kind": "LocalArgument", "kind": "LocalArgument",
"name": "organizationId" "name": "organizationId"
} },
], v2 = [
v1 = [
{ {
"kind": "Variable", "kind": "Variable",
"name": "id", "name": "id",
"variableName": "organizationId" "variableName": "organizationId"
} }
], ],
v2 = { v3 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "__typename", "name": "__typename",
"storageKey": null "storageKey": null
}, },
v3 = { v4 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "role", "name": "role",
"storageKey": null "storageKey": null
}, },
v4 = { v5 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "totalCount", "name": "totalCount",
"storageKey": null "storageKey": null
}, },
v5 = { v6 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
@@ -83,7 +87,10 @@ v5 = {
}; };
return { return {
"fragment": { "fragment": {
"argumentDefinitions": (v0/*: any*/), "argumentDefinitions": [
(v0/*: any*/),
(v1/*: any*/)
],
"kind": "Fragment", "kind": "Fragment",
"metadata": null, "metadata": null,
"name": "MembershipLayoutQuery", "name": "MembershipLayoutQuery",
@@ -92,13 +99,13 @@ return {
"kind": "RequiredField", "kind": "RequiredField",
"field": { "field": {
"alias": "organization", "alias": "organization",
"args": (v1/*: any*/), "args": (v2/*: any*/),
"concreteType": null, "concreteType": null,
"kind": "LinkedField", "kind": "LinkedField",
"name": "node", "name": "node",
"plural": false, "plural": false,
"selections": [ "selections": [
(v2/*: any*/), (v3/*: any*/),
{ {
"kind": "InlineFragment", "kind": "InlineFragment",
"selections": [ "selections": [
@@ -112,10 +119,17 @@ return {
"kind": "FragmentSpread", "kind": "FragmentSpread",
"name": "SessionDropdownFragment" "name": "SessionDropdownFragment"
}, },
{
"condition": "hideSidebar",
"kind": "Condition",
"passingValue": false,
"selections": [
{ {
"args": null, "args": null,
"kind": "FragmentSpread", "kind": "FragmentSpread",
"name": "SidebarFragment" "name": "SidebarFragment"
}
]
}, },
{ {
"kind": "RequiredField", "kind": "RequiredField",
@@ -127,7 +141,7 @@ return {
"name": "viewerMembership", "name": "viewerMembership",
"plural": false, "plural": false,
"selections": [ "selections": [
(v3/*: any*/) (v4/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
@@ -169,7 +183,7 @@ return {
"selections": [ "selections": [
{ {
"kind": "RequiredField", "kind": "RequiredField",
"field": (v4/*: any*/), "field": (v5/*: any*/),
"action": "THROW" "action": "THROW"
} }
], ],
@@ -188,19 +202,22 @@ return {
}, },
"kind": "Request", "kind": "Request",
"operation": { "operation": {
"argumentDefinitions": (v0/*: any*/), "argumentDefinitions": [
(v1/*: any*/),
(v0/*: any*/)
],
"kind": "Operation", "kind": "Operation",
"name": "MembershipLayoutQuery", "name": "MembershipLayoutQuery",
"selections": [ "selections": [
{ {
"alias": "organization", "alias": "organization",
"args": (v1/*: any*/), "args": (v2/*: any*/),
"concreteType": null, "concreteType": null,
"kind": "LinkedField", "kind": "LinkedField",
"name": "node", "name": "node",
"plural": false, "plural": false,
"selections": [ "selections": [
(v2/*: any*/), (v3/*: any*/),
{ {
"kind": "InlineFragment", "kind": "InlineFragment",
"selections": [ "selections": [
@@ -247,7 +264,7 @@ return {
"name": "email", "name": "email",
"storageKey": null "storageKey": null
}, },
(v5/*: any*/) (v6/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
@@ -266,15 +283,20 @@ return {
"name": "fullName", "name": "fullName",
"storageKey": null "storageKey": null
}, },
(v5/*: any*/) (v6/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
(v5/*: any*/), (v6/*: any*/),
(v3/*: any*/) (v4/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
{
"condition": "hideSidebar",
"kind": "Condition",
"passingValue": false,
"selections": [
{ {
"alias": "canListMeetings", "alias": "canListMeetings",
"args": [ "args": [
@@ -535,11 +557,13 @@ return {
"name": "permission", "name": "permission",
"storageKey": "permission(action:\"core:state-of-applicability:list\")" "storageKey": "permission(action:\"core:state-of-applicability:list\")"
} }
]
}
], ],
"type": "Organization", "type": "Organization",
"abstractKey": null "abstractKey": null
}, },
(v5/*: any*/) (v6/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
@@ -559,27 +583,27 @@ return {
"name": "pendingInvitations", "name": "pendingInvitations",
"plural": false, "plural": false,
"selections": [ "selections": [
(v4/*: any*/) (v5/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
(v5/*: any*/) (v6/*: any*/)
], ],
"storageKey": null "storageKey": null
} }
] ]
}, },
"params": { "params": {
"cacheID": "f39bc9faafcfb9d3e6482e088a3cae1e", "cacheID": "6b0b3a64c02e1c0ff744e57b395d14c8",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "MembershipLayoutQuery", "name": "MembershipLayoutQuery",
"operationKind": "query", "operationKind": "query",
"text": "query MembershipLayoutQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n ... on Organization {\n ...MembershipsDropdown_organizationFragment\n ...SessionDropdownFragment\n ...SidebarFragment\n viewerMembership {\n role\n id\n }\n }\n id\n }\n viewer {\n ...MembershipsDropdown_viewerFragment\n pendingInvitations {\n totalCount\n }\n id\n }\n}\n\nfragment MembershipsDropdown_organizationFragment on Organization {\n name\n}\n\nfragment MembershipsDropdown_viewerFragment on Identity {\n pendingInvitations {\n totalCount\n }\n}\n\nfragment SessionDropdownFragment on Organization {\n canDelete: permission(action: \"iam:organization:delete\")\n viewerMembership {\n identity {\n email\n id\n }\n profile {\n fullName\n id\n }\n id\n }\n}\n\nfragment SidebarFragment on Organization {\n canListMeetings: permission(action: \"core:meeting:list\")\n canListTasks: permission(action: \"core:task:list\")\n canListMeasures: permission(action: \"core:measures:list\")\n canListRisks: permission(action: \"core:risk:list\")\n canListFrameworks: permission(action: \"core:frameworks:list\")\n canListPeople: permission(action: \"core:people:list\")\n canListVendors: permission(action: \"core:vendor:list\")\n canListDocuments: permission(action: \"core:document:list\")\n canListAssets: permission(action: \"core:asset:list\")\n canListData: permission(action: \"core:datum:list\")\n canListAudits: permission(action: \"core:audit:list\")\n canListNonconformities: permission(action: \"core:nonconformity:list\")\n canListObligations: permission(action: \"core:obligation:list\")\n canListContinualImprovements: permission(action: \"core:continual-improvement:list\")\n canListProcessingActivities: permission(action: \"core:processing-activity:list\")\n canListRightsRequests: permission(action: \"core:rights-request:list\")\n canListSnapshots: permission(action: \"core:snapshot:list\")\n canGetTrustCenter: permission(action: \"core:trust-center:get\")\n canUpdateOrganization: permission(action: \"iam:organization:update\")\n canListStatesOfApplicability: permission(action: \"core:state-of-applicability:list\")\n}\n" "text": "query MembershipLayoutQuery(\n $organizationId: ID!\n $hideSidebar: Boolean!\n) {\n organization: node(id: $organizationId) {\n __typename\n ... on Organization {\n ...MembershipsDropdown_organizationFragment\n ...SessionDropdownFragment\n ...SidebarFragment @skip(if: $hideSidebar)\n viewerMembership {\n role\n id\n }\n }\n id\n }\n viewer {\n ...MembershipsDropdown_viewerFragment\n pendingInvitations {\n totalCount\n }\n id\n }\n}\n\nfragment MembershipsDropdown_organizationFragment on Organization {\n name\n}\n\nfragment MembershipsDropdown_viewerFragment on Identity {\n pendingInvitations {\n totalCount\n }\n}\n\nfragment SessionDropdownFragment on Organization {\n canDelete: permission(action: \"iam:organization:delete\")\n viewerMembership {\n identity {\n email\n id\n }\n profile {\n fullName\n id\n }\n id\n }\n}\n\nfragment SidebarFragment on Organization {\n canListMeetings: permission(action: \"core:meeting:list\")\n canListTasks: permission(action: \"core:task:list\")\n canListMeasures: permission(action: \"core:measures:list\")\n canListRisks: permission(action: \"core:risk:list\")\n canListFrameworks: permission(action: \"core:frameworks:list\")\n canListPeople: permission(action: \"core:people:list\")\n canListVendors: permission(action: \"core:vendor:list\")\n canListDocuments: permission(action: \"core:document:list\")\n canListAssets: permission(action: \"core:asset:list\")\n canListData: permission(action: \"core:datum:list\")\n canListAudits: permission(action: \"core:audit:list\")\n canListNonconformities: permission(action: \"core:nonconformity:list\")\n canListObligations: permission(action: \"core:obligation:list\")\n canListContinualImprovements: permission(action: \"core:continual-improvement:list\")\n canListProcessingActivities: permission(action: \"core:processing-activity:list\")\n canListRightsRequests: permission(action: \"core:rights-request:list\")\n canListSnapshots: permission(action: \"core:snapshot:list\")\n canGetTrustCenter: permission(action: \"core:trust-center:get\")\n canUpdateOrganization: permission(action: \"iam:organization:update\")\n canListStatesOfApplicability: permission(action: \"core:state-of-applicability:list\")\n}\n"
} }
}; };
})(); })();
(node as any).hash = "6e16255ebbb75840ce8ec057a453bbf0"; (node as any).hash = "2d75823d6ae9eee901e54b71d4c397cf";
export default node; export default node;

View File

@@ -10,13 +10,13 @@ import { useTranslate } from "@probo/i18n";
import { CoreRelayProvider } from "/providers/CoreRelayProvider"; import { CoreRelayProvider } from "/providers/CoreRelayProvider";
export const membershipLayoutQuery = graphql` export const membershipLayoutQuery = graphql`
query MembershipLayoutQuery($organizationId: ID!) { query MembershipLayoutQuery($organizationId: ID!, $hideSidebar: Boolean!) {
organization: node(id: $organizationId) @required(action: THROW) { organization: node(id: $organizationId) @required(action: THROW) {
__typename __typename
... on Organization { ... on Organization {
...MembershipsDropdown_organizationFragment ...MembershipsDropdown_organizationFragment
...SessionDropdownFragment ...SessionDropdownFragment
...SidebarFragment ...SidebarFragment @skip(if: $hideSidebar)
viewerMembership @required(action: THROW) { viewerMembership @required(action: THROW) {
role role
} }
@@ -32,9 +32,10 @@ export const membershipLayoutQuery = graphql`
`; `;
export function MembershipLayout(props: { export function MembershipLayout(props: {
hideSidebar?: boolean;
queryRef: PreloadedQuery<MembershipLayoutQuery>; queryRef: PreloadedQuery<MembershipLayoutQuery>;
}) { }) {
const { queryRef } = props; const { hideSidebar = false, queryRef } = props;
const { __ } = useTranslate(); const { __ } = useTranslate();
@@ -73,7 +74,7 @@ export function MembershipLayout(props: {
</Suspense> </Suspense>
</> </>
} }
sidebar={<Sidebar fKey={organization} />} sidebar={!hideSidebar && <Sidebar fKey={organization} />}
> >
<CoreRelayProvider> <CoreRelayProvider>
<Outlet context={organization.viewerMembership.role} /> <Outlet context={organization.viewerMembership.role} />

View File

@@ -15,6 +15,7 @@ function MembershipLayoutLoader() {
useEffect(() => { useEffect(() => {
loadQuery({ loadQuery({
organizationId, organizationId,
hideSidebar: false,
}); });
}, [loadQuery, organizationId]); }, [loadQuery, organizationId]);

View File

@@ -0,0 +1,42 @@
import { useQueryLoader } from "react-relay";
import { Suspense, useEffect } from "react";
import { Skeleton } from "@probo/ui";
import { useOrganizationId } from "/hooks/useOrganizationId";
import { IAMRelayProvider } from "/providers/IAMRelayProvider";
import {
MembershipLayout,
membershipLayoutQuery,
} from "/pages/iam/memberships/MembershipLayout";
import type { MembershipLayoutQuery } from "/__generated__/iam/MembershipLayoutQuery.graphql";
function EmployeeLayoutLoader() {
const organizationId = useOrganizationId();
const [queryRef, loadQuery] = useQueryLoader<MembershipLayoutQuery>(
membershipLayoutQuery,
);
useEffect(() => {
loadQuery({
organizationId,
hideSidebar: true,
});
}, [loadQuery, organizationId]);
if (!queryRef) {
return <Skeleton className="w-full h-screen" />;
}
return (
<Suspense fallback={<Skeleton className="w-full h-screen" />}>
<MembershipLayout queryRef={queryRef} hideSidebar />
</Suspense>
);
}
export default function () {
return (
<IAMRelayProvider>
<EmployeeLayoutLoader />
</IAMRelayProvider>
);
}

View File

@@ -120,7 +120,7 @@ const routes = [
path: "/organizations/:organizationId/employee", path: "/organizations/:organizationId/employee",
Fallback: () => "fallback employee...", Fallback: () => "fallback employee...",
Component: lazy( Component: lazy(
() => import("./pages/iam/memberships/MembershipLayoutLoader"), () => import("./pages/organizations/employee/EmployeeLayoutLoader"),
), ),
ErrorBoundary: ErrorBoundary, ErrorBoundary: ErrorBoundary,
children: [ children: [

View File

@@ -49,7 +49,7 @@ export function Layout({ header, sidebar, children }: Props) {
{header} {header}
</header> </header>
<div className="flex h-screen" id="main"> <div className="flex h-screen" id="main">
<Sidebar>{sidebar}</Sidebar> {sidebar && <Sidebar>{sidebar}</Sidebar>}
<main <main
className={clsx( className={clsx(
"overflow-y-auto w-full mt-12 transition-all duration-300", "overflow-y-auto w-full mt-12 transition-all duration-300",