mirror of
https://github.com/biersoeckli/QuickStack.git
synced 2026-02-17 18:28:48 -06:00
added layout for app overview page
This commit is contained in:
@@ -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.');
|
||||
});
|
||||
});
|
||||
@@ -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 (
|
||||
55
src/app/project/app/[appId]/layout.tsx
Normal file
55
src/app/project/app/[appId]/layout.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
|
||||
32
src/app/project/app/[appId]/page.tsx
Normal file
32
src/app/project/app/[appId]/page.tsx
Normal 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'} />
|
||||
)
|
||||
}
|
||||
@@ -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>
|
||||
)
|
||||
}
|
||||
@@ -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")}`);
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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>;
|
||||
|
||||
@@ -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>;
|
||||
|
||||
|
||||
@@ -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>;
|
||||
Reference in New Issue
Block a user