Skip to content

Commit

Permalink
Setup home page
Browse files Browse the repository at this point in the history
  • Loading branch information
Cyberboss committed Oct 20, 2024
1 parent 78f5c1c commit 5f06e82
Show file tree
Hide file tree
Showing 11 changed files with 215 additions and 18 deletions.
20 changes: 6 additions & 14 deletions src/components/core/Router/Router.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,14 @@
import { lazy, Suspense } from "react";
import { createBrowserRouter, RouterProvider } from "react-router-dom";

import HomeRoutes from "../../routed/Home/HomeRoutes";

import ProtectedRoute from "./ProtectedRoute/ProtectedRoute";
import RethrowRouteError from "./RethrowRouteError/RethrowRouteError";

import devDelay from "@/lib/devDelay";
import { ICredentials } from "@/lib/Credentials";
import Loading from "@/components/utils/Loading/Loading";

const Configuration = lazy(
async () =>
await devDelay(
() => import("@/components/routed/Configuration/Configuration"),
"Component Load: Configuration"
)
);
import { ICredentials } from "@/lib/Credentials";
import devDelay from "@/lib/devDelay";

const Home = lazy(
async () =>
Expand Down Expand Up @@ -50,21 +44,19 @@ const Router = (props: IProps) => {
element: <Layout />,
errorElement: <RethrowRouteError />,
children: [
{
path: "config",
element: <Configuration />
},
{
path: "login",
element: <Login setTemporaryCredentials={props.setTemporaryCredentials} />
},
...HomeRoutes.filter(route => route.unprotected),
{
element: <ProtectedRoute />,
children: [
{
path: "",
element: <Home />
},
...HomeRoutes.filter(route => !route.unprotected),
{
path: "*",
element: <NotFound />
Expand Down
39 changes: 38 additions & 1 deletion src/components/routed/Home/Home.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { Meta, StoryObj } from "@storybook/react";

import { HomeCardPermissionsQuery } from "./graphql/__generated__/HomeCardPermissionsQuery.graphql";
import HomeCardPermissions from "./graphql/HomeCardPermissions";
import Home from "./Home";

import { WithRelayParameters } from "@/../.storybook/MockRelayEnvironment";
import SessionContext from "@/context/session/SessionContext";
import { DefaultUserPasswordCredentials, UserPasswordCredentials } from "@/lib/Credentials";

Expand All @@ -13,6 +16,7 @@ const TestComponent = (props: IArgs) => {
const session = {
currentSession: {
bearer: "asdf",
userId: "fdsa",
originalCredentials: props.defaultCredentials
? new DefaultUserPasswordCredentials()
: new UserPasswordCredentials("asdf", "asdf")
Expand All @@ -27,6 +31,26 @@ const TestComponent = (props: IArgs) => {
);
};

const CreateRelay = (fieldsEnabled: boolean): WithRelayParameters<HomeCardPermissionsQuery> => ({
query: HomeCardPermissions,
mockResolvers: {
PermissionSet: () => ({
administrationRights: {
canChangeVersion: fieldsEnabled,
canDownloadLogs: fieldsEnabled,
canEditOwnPassword: fieldsEnabled,
canReadUsers: fieldsEnabled,
canUploadVersion: fieldsEnabled,
canWriteUsers: fieldsEnabled
},
instanceManagerRights: {
canList: fieldsEnabled,
canRead: fieldsEnabled
}
})
}
});

const config: Meta<typeof TestComponent> = {
component: TestComponent,
title: "Routed/Home"
Expand All @@ -36,10 +60,23 @@ export default config;

type Story = StoryObj<typeof config>;

export const Default: Story = {};
export const Default: Story = {
parameters: {
relay: CreateRelay(true)
}
};

export const DisabledPerms: Story = {
parameters: {
relay: CreateRelay(false)
}
};

export const WithDefaultAdminPassword: Story = {
args: {
defaultCredentials: true
},
parameters: {
relay: CreateRelay(true)
}
};
21 changes: 19 additions & 2 deletions src/components/routed/Home/Home.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { FormattedMessage } from "react-intl";
import { useLazyLoadQuery } from "react-relay";

import { HomeCardPermissionsQuery } from "./graphql/__generated__/HomeCardPermissionsQuery.graphql";
import HomeCardPermissions from "./graphql/HomeCardPermissions";
import HomeCard from "./HomeCard/HomeCard";
import HomeRoutes from "./HomeRoutes";

import { Alert, AlertDescription } from "@/components/ui/alert";
import useSession from "@/context/session/useSession";
Expand All @@ -8,15 +14,26 @@ const Home = () => {
const usingDefaultCredentials =
!!session.currentSession?.originalCredentials.defaultCredentials;

const data = useLazyLoadQuery<HomeCardPermissionsQuery>(HomeCardPermissions, {
userID: session.currentSession!.userId
});

return (
<>
{usingDefaultCredentials ? (
<Alert className="clearfix bg-warning">
<AlertDescription className="font-bold text-warning-foreground">
<Alert className="clearfix bg-warning mb-4">
<AlertDescription className="font-bold text-warning-foreground text-lg text-center">
<FormattedMessage id="error.app.default_creds" />
</AlertDescription>
</Alert>
) : null}
<div className="flex flex-row flex-wrap justify-center">
{HomeRoutes.map(route => (
<div className="basis-full sm:basis-1/2 md:basis-1/3 lg:basis-1/4">
<HomeCard key={route.localeNameId} {...route} queryData={data} />
</div>
))}
</div>
</>
);
};
Expand Down
29 changes: 29 additions & 0 deletions src/components/routed/Home/HomeCard/HomeCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { FormattedMessage } from "react-intl";
import { Link } from "react-router-dom";

import IHomeCardProps from "./HomeCardProps";

import { Card, CardContent, CardFooter } from "@/components/ui/card";

const HomeCard = (props: IHomeCardProps) => {
const enabled = props.calculateEnabled ? props.calculateEnabled(props.queryData) : true;
const RenderCard = () => (
<Card
className={enabled ? "text-primary hover:text-primary-foreground" : "text-destructive"}>
<CardContent style={{ height: "245px" }} className="text-center border-0">
<FontAwesomeIcon className="w-4/5 h-4/5 mt-4 mb-4" icon={props.icon} />
<hr />
</CardContent>
<CardFooter className={"justify-center font-bold text-lg" + (enabled ? "" : "italic")}>
<FormattedMessage id={props.localeNameId} />
</CardFooter>
</Card>
);
return (
<div className="m-4">
{enabled ? <Link to={props.path}>{RenderCard()}</Link> : RenderCard()}
</div>
);
};
export default HomeCard;
11 changes: 11 additions & 0 deletions src/components/routed/Home/HomeCard/HomeCardProps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { IconProp } from "@fortawesome/fontawesome-svg-core";

import { HomeCardPermissionsQuery$data } from "../graphql/__generated__/HomeCardPermissionsQuery.graphql";

export default interface IHomeCardProps {
icon: IconProp;
localeNameId: string;
path: string;
calculateEnabled?: (data: HomeCardPermissionsQuery$data) => boolean | undefined;
queryData: HomeCardPermissionsQuery$data;
}
83 changes: 83 additions & 0 deletions src/components/routed/Home/HomeRoutes.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import {
faCogs,
faHdd,
faInfoCircle,
faKey,
faTools,
faUser
} from "@fortawesome/free-solid-svg-icons";
import { lazy } from "react";
import { RouteObject } from "react-router-dom";

import HomeCardProps from "./HomeCard/HomeCardProps";

import NotFound from "@/components/core/NotFound/NotFound";
import devDelay from "@/lib/devDelay";

const Configuration = lazy(
async () =>
await devDelay(
() => import("@/components/routed/Configuration/Configuration"),
"Component Load: Configuration"
)
);

interface IHomeRouteProtected {
unprotected?: boolean;
}

type HomeRoute = RouteObject & IHomeRouteProtected & Omit<HomeCardProps, "queryData">;

const HomeRoutes: HomeRoute[] = [
{
path: "instances",
icon: faHdd,
localeNameId: "routes.instancelist",
calculateEnabled: data =>
data.node?.effectivePermissionSet?.instanceManagerRights.canList ||
data.node?.effectivePermissionSet?.instanceManagerRights.canRead,
element: <NotFound />
},
{
path: "users",
icon: faUser,
localeNameId: "routes.usermanager",
calculateEnabled: data =>
data.node?.effectivePermissionSet?.administrationRights.canReadUsers ||
data.node?.effectivePermissionSet?.administrationRights.canWriteUsers,
element: <NotFound />
},
{
path: "admin",
icon: faTools,
localeNameId: "routes.admin",
calculateEnabled: data =>
data.node?.effectivePermissionSet?.administrationRights.canChangeVersion ||
data.node?.effectivePermissionSet?.administrationRights.canDownloadLogs ||
data.node?.effectivePermissionSet?.administrationRights.canUploadVersion,
element: <NotFound />
},
{
path: "/users/passwd",
icon: faKey,
localeNameId: "routes.passwd",
calculateEnabled: data =>
data.node?.effectivePermissionSet?.administrationRights.canEditOwnPassword,
element: <NotFound />
},
{
path: "/config",
icon: faCogs,
localeNameId: "routes.config",
element: <Configuration />,
unprotected: true
},
{
path: "/info",
icon: faInfoCircle,
localeNameId: "routes.info",
element: <NotFound />
}
];

export default HomeRoutes;
26 changes: 26 additions & 0 deletions src/components/routed/Home/graphql/HomeCardPermissions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { graphql } from "react-relay";

const HomeCardPermissions = graphql`
query HomeCardPermissionsQuery($userID: ID!) {
node(id: $userID) {
... on User {
effectivePermissionSet {
administrationRights {
canChangeVersion
canDownloadLogs
canUploadVersion
canEditOwnPassword
canReadUsers
canWriteUsers
}
instanceManagerRights {
canList
canRead
}
}
}
}
}
`;

export default HomeCardPermissions;
1 change: 0 additions & 1 deletion src/components/routed/Login/Login.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,6 @@ const config: Meta<typeof TestComponent> = {
}
},
parameters: {
query: GetOAuthProviders,
relay
}
};
Expand Down
1 change: 1 addition & 0 deletions src/components/routed/Login/Login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ const Login = (props: IProps) => {
if (response.login.loginResult) {
session.setSession({
bearer: response.login.loginResult.bearer,
userId: response.login.loginResult.user.id,
originalCredentials: credentials
});
}
Expand Down
1 change: 1 addition & 0 deletions src/components/routed/Login/graphql/ServerLogin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const ServerLogin = graphql`
loginResult {
bearer
user {
id
...CommonUserDetailsFragment
}
}
Expand Down
1 change: 1 addition & 0 deletions src/context/session/Session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ import { ICredentials } from "@/lib/Credentials";

export default interface ISession {
bearer: string;
userId: string;
originalCredentials: ICredentials;
}

0 comments on commit 5f06e82

Please sign in to comment.