added layout for app overview page

This commit is contained in:
biersoeckli
2024-11-27 09:00:02 +00:00
parent 6d43c30c9d
commit 09e7c07af9
33 changed files with 105 additions and 79 deletions

View File

@@ -27,4 +27,4 @@ export const startApp = async (appId: string) =>
const app = await appService.getExtendedById(appId);
await deploymentService.setReplicasForDeployment(app.projectId, app.id, app.replicas);
return new SuccessActionResult(undefined, 'Successfully started app.');
});
});

View File

@@ -25,7 +25,7 @@ export default function AppTabs({
const router = useRouter();
const openTab = (tabName: string) => {
router.push(`/project/app/${tabName}?appId=${app.id}`);
router.push(`/project/app/${app.id}?tabName=${tabName}`);
}
return (

View File

@@ -0,0 +1,55 @@
import { Inter } from "next/font/google";
import { getAuthUserSession } from "@/server/utils/action-wrapper.utils";
import appService from "@/server/services/app.service";
import {
Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbSeparator,
} from "@/components/ui/breadcrumb"
import PageTitle from "@/components/custom/page-title";
import AppActionButtons from "./app-action-buttons";
export default async function RootLayout({
children,
params
}: Readonly<{
params: { appId: string }
children: React.ReactNode;
}>) {
await getAuthUserSession();
const appId = params?.appId;
if (!appId) {
return <p>Could not find app with id {appId}</p>
}
const app = await appService.getExtendedById(appId);
return (
<div className="flex-1 space-y-6 p-8 pt-6">
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink href="/">Projects</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbLink href={`/project?projectId=${app.projectId}`}>{app.project.name}</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbLink>{app.name}</BreadcrumbLink>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>
<PageTitle
title={app.name}
subtitle={`App ID: ${app.id}`}>
</PageTitle>
<AppActionButtons app={app} />
{children}
</div>
);
}

View File

@@ -0,0 +1,32 @@
import { getAuthUserSession } from "@/server/utils/action-wrapper.utils";
import appService from "@/server/services/app.service";
import {
Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbSeparator,
} from "@/components/ui/breadcrumb"
import PageTitle from "@/components/custom/page-title";
import AppTabs from "./app-tabs";
import AppActionButtons from "./app-action-buttons";
import buildService from "@/server/services/build.service";
export default async function AppPage({
searchParams,
params
}: {
searchParams?: { [key: string]: string | undefined };
params: { appId: string }
}) {
await getAuthUserSession();
const appId = params?.appId;
if (!appId) {
return <p>Could not find app with id {appId}</p>
}
const app = await appService.getExtendedById(appId);
return (
<AppTabs app={app} tabName={searchParams?.tabName ?? 'overview'} />
)
}

View File

@@ -1,54 +0,0 @@
import { getAuthUserSession } from "@/server/utils/action-wrapper.utils";
import appService from "@/server/services/app.service";
import {
Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbSeparator,
} from "@/components/ui/breadcrumb"
import PageTitle from "@/components/custom/page-title";
import AppTabs from "./app-tabs";
import AppActionButtons from "./app-action-buttons";
import buildService from "@/server/services/build.service";
export default async function AppPage({
searchParams,
params
}: {
searchParams?: { [key: string]: string | undefined };
params: { tabName: string };
}) {
await getAuthUserSession();
const appId = searchParams?.appId;
if (!appId) {
return <p>Could not find app with id {appId}</p>
}
const app = await appService.getExtendedById(appId);
return (
<div className="flex-1 space-y-6 p-8 pt-6">
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink href="/">Projects</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbLink href={`/project?projectId=${app.projectId}`}>{app.project.name}</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbLink>{app.name}</BreadcrumbLink>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>
<PageTitle
title={app.name}
subtitle={`App ID: ${app.id}`}>
</PageTitle>
<AppActionButtons app={app} />
<AppTabs app={app} tabName={params.tabName} />
</div>
)
}

View File

@@ -1,7 +0,0 @@
import { redirect } from "next/navigation";
// redirects to default route "general" for the app
export async function GET(request: Request) {
const url = new URL(request.url);
redirect(`/project/app/overview?appId=${url.searchParams.get("appId")}`);
}

View File

@@ -32,7 +32,7 @@ export default function AppTable({ data }: { data: App[] }) {
["updatedAt", "Updated At", false, (item) => formatDateTime(item.updatedAt)],
]}
data={data}
onItemClickLink={(item) => `/project/app?appId=${item.id}`}
onItemClickLink={(item) => `/project/app/${item.id}`}
actionCol={(item) =>
<>
<div className="flex">
@@ -46,7 +46,7 @@ export default function AppTable({ data }: { data: App[] }) {
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuLabel>Actions</DropdownMenuLabel>
<Link href={`/project/app?appId=${item.id}`}>
<Link href={`/project/app/${item.id}`}>
<DropdownMenuItem>
<span>Show App Details</span>
</DropdownMenuItem>

View File

@@ -4,24 +4,24 @@ export const appSourceInfoInputZodModel = z.object({
sourceType: z.enum(["GIT", "CONTAINER"]),
containerImageSource: z.string().nullish(),
gitUrl: z.string().nullish(),
gitBranch: z.string().nullish(),
gitUsername: z.string().nullish(),
gitToken: z.string().nullish(),
dockerfilePath: z.string().nullish(),
gitUrl: z.string().trim().nullish(),
gitBranch: z.string().trim().nullish(),
gitUsername: z.string().trim().nullish(),
gitToken: z.string().trim().nullish(),
dockerfilePath: z.string().trim().nullish(),
});
export type AppSourceInfoInputModel = z.infer<typeof appSourceInfoInputZodModel>;
export const appSourceInfoGitZodModel = z.object({
gitUrl: z.string(),
gitBranch: z.string(),
gitUsername: z.string().nullish(),
gitToken: z.string().nullish(),
dockerfilePath: z.string(),
gitUrl: z.string().trim(),
gitBranch: z.string().trim(),
gitUsername: z.string().trim().nullish(),
gitToken: z.string().trim().nullish(),
dockerfilePath: z.string().trim(),
});
export type AppSourceInfoGitModel = z.infer<typeof appSourceInfoGitZodModel>;
export const appSourceInfoContainerZodModel = z.object({
containerImageSource: z.string(),
containerImageSource: z.string().trim(),
});
export type AppSourceInfoContainerModel = z.infer<typeof appSourceInfoContainerZodModel>;

View File

@@ -1,8 +1,8 @@
import { z } from "zod";
export const authFormInputSchemaZod = z.object({
email: z.string().email(),
password: z.string().min(1)
email: z.string().trim().email(),
password: z.string().trim().min(1)
});
export type AuthFormInputSchema = z.infer<typeof authFormInputSchemaZod>;

View File

@@ -1,7 +1,7 @@
import { z } from "zod";
export const totpZodModel = z.object({
totp: z.string(),
totp: z.string().trim(),
})
export type TotpModel = z.infer<typeof totpZodModel>;