diff --git a/apps/app/src/app/page.tsx b/apps/app/src/app/page.tsx
index 035ab9c18..725d8de70 100644
--- a/apps/app/src/app/page.tsx
+++ b/apps/app/src/app/page.tsx
@@ -3,8 +3,10 @@ import { MainNav } from "~/components/ui/main-nav";
import { GenerateToken } from "~/components/generate-token";
import { ExtractStartForm } from "~/components/extract-start-form";
import { TransformStartForm } from "~/components/transform-start-form";
+import { getEnvTenants } from "~/components/tenant.env";
export default function Page() {
+ const tenants = getEnvTenants(); // getServerSideProps is deprecated. createServerContext documentation lackluster
return (
<>
@@ -19,8 +21,8 @@ export default function Page() {
-
-
+
+
>
);
-}
+}
\ No newline at end of file
diff --git a/apps/app/src/components/extract-start-form.tsx b/apps/app/src/components/extract-start-form.tsx
index c6371e7ba..c9f28876b 100644
--- a/apps/app/src/components/extract-start-form.tsx
+++ b/apps/app/src/components/extract-start-form.tsx
@@ -3,9 +3,13 @@ import { useAuth } from '@clerk/nextjs';
import { useState } from 'react';
import type { ChangeEvent, Dispatch, SetStateAction } from 'react';
import { Input } from './ui/input';
+import { TenantPicker } from './tenant-picker';
+import type { Tenant } from './tenant.env';
-
-export function ExtractStartForm() {
+type ExtractStartFormProps = {
+ TENANTS: Tenant[] | undefined
+}
+export function ExtractStartForm({ TENANTS }: ExtractStartFormProps) {
const { getToken } = useAuth();
const currentDate = new Date();
currentDate.setMonth(currentDate.getMonth() - 6);
@@ -18,6 +22,7 @@ export function ExtractStartForm() {
const [to, setTo] = useState(new Date().toISOString().slice(0, 10));
const [status, setStatus] = useState('---');
const [body, setBody] = useState('');
+ const [tenantId, setTenantId] = useState((TENANTS || [])[0]?.id || -1);
const handleInputChange = (stateSetter: Dispatch>) => (ev: ChangeEvent) => stateSetter(ev.target.value);
@@ -25,13 +30,14 @@ export function ExtractStartForm() {
const handleSubmit = async () => {
if (!process.env.NEXT_PUBLIC_EXTRACT_API_URL) return console.error('Missing ENV variable: NEXT_PUBLIC_EXTRACT_API_URL');
+ if (tenantId === -1) return console.error(`Invalid ENV variable: TENANTS`);
setStatus('...');
setBody('');
const token = await getToken({ template: 'dashboard' });
if (!token) return;
- const requestBody = JSON.stringify({ repositoryId, repositoryName, namespaceName, sourceControl, from: new Date(from), to: new Date(to) });
+ const requestBody = JSON.stringify({ repositoryId, repositoryName, namespaceName, sourceControl, from: new Date(from), to: new Date(to), tenantId });
const res = await fetch(process.env.NEXT_PUBLIC_EXTRACT_API_URL, {
method: 'post',
@@ -81,6 +87,12 @@ export function ExtractStartForm() {
|
|
+
+ tenant: |
+
+
+ |
+
diff --git a/apps/app/src/components/tenant-picker.tsx b/apps/app/src/components/tenant-picker.tsx
new file mode 100644
index 000000000..2e7bca9a0
--- /dev/null
+++ b/apps/app/src/components/tenant-picker.tsx
@@ -0,0 +1,25 @@
+"use client"
+import type { ChangeEvent } from "react";
+import type { Tenant } from "./tenant.env";
+
+type TenantPickerProps = {
+ tenants: Tenant[] | undefined
+ setTenantId: (tenantId: number) => void;
+}
+export function TenantPicker({ tenants, setTenantId }: TenantPickerProps) {
+
+ if (tenants === undefined) return (Invalid environment varibale: TENANTS);
+
+ if (tenants.length === 0) return (Empty tenancy config);
+
+ const handleSelectChange = (ev: ChangeEvent) => setTenantId(Number(ev.target.value));
+
+ return (
+
+ );
+
+}
diff --git a/apps/app/src/components/tenant.env.ts b/apps/app/src/components/tenant.env.ts
new file mode 100644
index 000000000..64db07f05
--- /dev/null
+++ b/apps/app/src/components/tenant.env.ts
@@ -0,0 +1,34 @@
+import { z } from "zod";
+
+const ENVSchema = z.object({
+ TENANTS: z.string(),
+})
+const TenantSchema = z.object({
+ id: z.number(),
+ tenant: z.string(),
+ dbUrl: z.string(),
+});
+const TenantArraySchema = z.array(TenantSchema);
+
+const processEnv = () => {
+ const validEnv = ENVSchema.safeParse(process.env);
+ if (!validEnv.success) {
+ console.error(`Missing required environment variable 'TENANT'`);
+ return undefined;
+ }
+
+ const validTenantArray = TenantArraySchema.safeParse(JSON.parse(validEnv.data.TENANTS));
+ if (!validTenantArray.success) {
+ console.error("Invalid environment variable 'TENANTS' value:", ...validTenantArray.error.issues);
+ return undefined;
+ }
+
+ return validTenantArray.data;
+}
+
+const TENANTS = processEnv();
+
+
+export const getEnvTenants = () => TENANTS;
+
+export type Tenant = z.infer;
diff --git a/apps/app/src/components/transform-start-form.tsx b/apps/app/src/components/transform-start-form.tsx
index 55b2b99bf..d3eec7011 100644
--- a/apps/app/src/components/transform-start-form.tsx
+++ b/apps/app/src/components/transform-start-form.tsx
@@ -1,15 +1,23 @@
"use client"
import { useAuth } from '@clerk/nextjs';
import { useState } from 'react';
+import type { Tenant } from './tenant.env';
+import { TenantPicker } from './tenant-picker';
-
-export function TransformStartForm() {
+type TransformStartFormProps = {
+ TENANTS: Tenant[] | undefined
+}
+export function TransformStartForm({ TENANTS }: TransformStartFormProps) {
const { getToken } = useAuth();
+ const [tenantId, setTenantId] = useState((TENANTS || [])[0]?.id || -1);
const [status, setStatus] = useState('---');
const [body, setBody] = useState('');
const handleClick = async () => {
if (!process.env.NEXT_PUBLIC_TRANSFORM_API_URL) return console.error('Missing ENV variable: NEXT_PUBLIC_TRANSFORM_API_URL');
+ if (tenantId === -1) return console.error(`Invalid ENV variable: TENANTS`);
+ const requestBody = JSON.stringify({ tenantId });
+
setStatus('...');
setBody('');
@@ -18,6 +26,7 @@ export function TransformStartForm() {
const res = await fetch(process.env.NEXT_PUBLIC_TRANSFORM_API_URL, {
method: 'post',
+ body: requestBody,
headers: {
'Authorization': 'Bearer ' + token
}
@@ -36,6 +45,7 @@ export function TransformStartForm() {
+ tenant:
{status}
{body}