Skip to content

Commit

Permalink
feat: add auth
Browse files Browse the repository at this point in the history
Signed-off-by: Jonathan Perchoc <[email protected]>
  • Loading branch information
jperchoc committed Dec 17, 2024
1 parent d35a9a1 commit cc6df1b
Show file tree
Hide file tree
Showing 9 changed files with 316 additions and 139 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { apiClient } from '@ovh-ux/manager-core-api';
import { PCIAi } from '..';

export interface TestType {
id?: string;
delay: number;
email: string;
monthlyThreshold: number;
}

export interface TestPostType extends PCIAi {
test: TestType;
}

export const getTest = async ({ projectId }: PCIAi) =>
apiClient.v6
.get(`/cloud/project/${projectId}/alerting`, {
headers: {
'X-Pagination-Mode': 'CachedObjectList-Pages',
'X-Pagination-Size': '50000',
},
})
.then((res) => res.data as string[]);

export const postTest = async ({ projectId, test }: TestPostType) =>
apiClient.v6
.post(`/cloud/project/${projectId}/alerting`, test)
.then((res) => res.data as TestType);

export const deleteTest = async ({ projectId, test }: TestPostType) =>
apiClient.v6.delete(`/cloud/project/${projectId}/alerting/${test.id}`);
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { useParams } from 'react-router-dom';
import {
QueryObserverOptions,
UseQueryResult,
useMutation,
useQueryClient,
} from '@tanstack/react-query';

import {
TestType,
deleteTest,
getTest,
postTest,
} from '@/data/api/test/test.api';
import { AIError } from '@/data/api';
import { useQueryImmediateRefetch } from '../useImmediateRefetch';

export function useGetTest(
projectId: string,
options: Omit<QueryObserverOptions, 'queryKey'> = {},
) {
const queryKey = [projectId, 'alerting'];
return useQueryImmediateRefetch({
queryKey,
queryFn: () => getTest({ projectId }),
...options,
}) as UseQueryResult<TestType[], Error>;
}

export interface PostMutateTestProps {
onError: (cause: AIError) => void;
onSuccess: (test?: TestType) => void;
}

export function usePostTest({ onError, onSuccess }: PostMutateTestProps) {
const queryClient = useQueryClient();
const { projectId } = useParams();
const mutation = useMutation({
mutationFn: (testInfo: TestType) => {
return postTest({ projectId, test: testInfo });
},
onError,
onSuccess: (data) => {
// invalidate notebook list to avoid displaying
// old list
queryClient.invalidateQueries({
queryKey: [projectId, 'alerting'],
});
onSuccess(data);
},
});

return {
postTest: (postInfo: TestType) => {
return mutation.mutate(postInfo);
},
...mutation,
};
}

export function useDeleteTest({ onError, onSuccess }: PostMutateTestProps) {
const queryClient = useQueryClient();
const { projectId } = useParams();
const mutation = useMutation({
mutationFn: (testInfo: TestType) => {
return deleteTest({ projectId, test: testInfo });
},
onError,
onSuccess: () => {
// invalidate notebook list to avoid displaying
// old list
queryClient.invalidateQueries({
queryKey: [projectId, 'alerting'],
});
onSuccess();
},
});

return {
deleteTest: (postInfo: TestType) => {
return mutation.mutate(postInfo);
},
...mutation,
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ export function useTrackPageAuto() {
name: injectedTrackingKey,
level2: PCI_LEVEL2,
});
console.debug('TRACK', injectedTrackingKey);
hasTrackedRef.current = true;
}, [location.pathname, params.serviceId]);

Expand Down
19 changes: 8 additions & 11 deletions packages/manager/apps/pci-ai-notebooks/src/pages/Root.layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import { defineCurrentPage } from '@ovh-ux/request-tagger';
import queryClient from '@/query.client';
import { useLoadingIndicatorContext } from '@/contexts/LoadingIndicator.context';
import { getProject } from '@/data/api/project/project.api';
import Breadcrumb from '@/components/breadcrumb/Breadcrumb.component';
import BreadcrumbItem from '@/components/breadcrumb/BreadcrumbItem.component';
import { Toaster } from '@/components/ui/toaster';
import PageLayout from '@/components/page-layout/PageLayout.component';
Expand All @@ -31,20 +30,19 @@ interface NotebooksLayoutProps {
};
request: Request;
}
// try to fetch the service data, redirect to service page if it fails
// try to get project details from project id, redirect if the projectId is invalid
export const Loader = async ({ params }: NotebooksLayoutProps) => {
const { projectId } = params;

// check if we have a correct projectId
return queryClient
.fetchQuery({
try {
await queryClient.fetchQuery({
queryKey: ['projectId', projectId],
queryFn: () => getProject(projectId),
})
.then(
() => null,
() => redirect(`/pci/projects`),
);
});
} catch (_error) {
return redirect(`/pci/projects`);
}
return null;
};

function RoutingSynchronisation() {
Expand Down Expand Up @@ -83,7 +81,6 @@ export default function Layout() {
return (
<PageLayout>
<UserActivityProvider timeout={USER_INACTIVITY_TIMEOUT}>
<Breadcrumb />
<RoutingSynchronisation />
<Outlet />
<Toaster />
Expand Down
34 changes: 9 additions & 25 deletions packages/manager/apps/pci-ai-notebooks/src/pages/Root.page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { redirect } from 'react-router-dom';
import queryClient from '@/query.client';
import Notebooks from './notebooks/Notebooks.page';
import { getNotebooks } from '@/data/api/ai/notebook/notebook.api';
import { getAuthorization } from '@/data/api/ai/authorization.api';

interface NotebooksProps {
params: {
Expand All @@ -11,32 +10,17 @@ interface NotebooksProps {
request: Request;
}

export const Loader = ({ params }: NotebooksProps) => {
export const Loader = async ({ params }: NotebooksProps) => {
// check if we have a correct category
const { projectId } = params;
return queryClient
.fetchQuery({
queryKey: [projectId, 'auth'],
queryFn: () => getAuthorization({ projectId }),
})
.then((auth) => {
if (!auth.authorized) {
return redirect(`/pci/projects/${projectId}/ai/notebooks/auth`);
}
return queryClient
.fetchQuery({
queryKey: [projectId, 'ai/notebooks'],
queryFn: () => getNotebooks({ projectId }),
})
.then((notebooks) => {
if (notebooks.length === 0) {
return redirect(
`/pci/projects/${projectId}/ai/notebooks/onboarding`,
);
}
return null;
});
});
const notebooks = await queryClient.fetchQuery({
queryKey: [projectId, 'ai/notebooks'],
queryFn: () => getNotebooks({ projectId }),
});
if (notebooks.length === 0) {
return redirect(`/pci/projects/${projectId}/ai/notebooks/onboarding`);
}
return null;
};

export default function Root() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { Outlet, redirect } from 'react-router-dom';
import Breadcrumb from '@/components/breadcrumb/Breadcrumb.component';
import queryClient from '@/query.client';
import { getTest } from '@/data/api/test/test.api';

interface WithAuthLayoutProps {
params: {
projectId: string;
};
request: Request;
}
// check if the user has authentication
export const Loader = async ({ params }: WithAuthLayoutProps) => {
const { projectId } = params;
try {
const authResult = await queryClient.fetchQuery({
queryKey: [projectId, 'alerting'],
queryFn: () => getTest({ projectId }),
});
if (authResult.length === 0) {
return redirect(`/pci/projects/${projectId}/ai/notebooks/auth`);
}
} catch (_error) {
return redirect(`/pci/projects/${projectId}/ai/notebooks/auth`);
}
return null;
};

export default function Layout() {
return (
<>
<Breadcrumb />
<Outlet />
</>
);
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
import { useTranslation } from 'react-i18next';
import { useNavigate, useParams } from 'react-router-dom';
import { AlertCircle, ArrowRight } from 'lucide-react';
import { redirect, useNavigate, useParams } from 'react-router-dom';
import { AlertCircle, ArrowRight, X } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { useToast } from '@/components/ui/use-toast';
import {
PostMutateAuthorizationProps,
usePostAuthorization,
} from '@/hooks/api/ai/authorization/usePostAuthorization.hook';
// import {
// PostMutateAuthorizationProps,
// usePostAuthorization,
// } from '@/hooks/api/ai/authorization/usePostAuthorization.hook';
import { Alert, AlertDescription } from '@/components/ui/alert';
import OvhLink from '@/components/links/OvhLink.component';
import usePciProject from '@/hooks/api/project/usePciProject.hook';
import { PlanCode } from '@/configuration/project';
import {
PostMutateTestProps,
useDeleteTest,
useGetTest,
usePostTest,
} from '@/hooks/api/test/useTest.hook';
import { TestType } from '@/data/api/test/test.api';
import Link from '@/components/links/Link.component';

export default function Auth() {
const { t } = useTranslation('pci-ai-notebooks/auth');
Expand All @@ -19,10 +27,13 @@ export default function Auth() {
const { projectId } = useParams();
const projectData = usePciProject();

const tests = useGetTest(projectId);

const isProjectDiscoveryMode =
projectData.data?.planCode === PlanCode.DISCOVERY;

const PostAuthorizationProps: PostMutateAuthorizationProps = {
// const PostAuthorizationProps: PostMutateAuthorizationProps = {
const PostTestProps: PostMutateTestProps = {
onError(err) {
toast.toast({
title: t(`formActiveUserToastErrorTitle`),
Expand All @@ -39,12 +50,21 @@ export default function Auth() {
},
};

const { postAuthorization } = usePostAuthorization(PostAuthorizationProps);
// const { postAuthorization } = usePostAuthorization(PostAuthorizationProps);
const { postTest } = usePostTest(PostTestProps);
const { deleteTest } = useDeleteTest(PostTestProps);

const activateProject = () => {
postAuthorization({
projectId,
});
// postAuthorization({
// projectId,
// });

const test: TestType = {
delay: 3600,
email: '[email protected]',
monthlyThreshold: 1,
};
postTest(test);
};

return (
Expand Down Expand Up @@ -92,6 +112,21 @@ export default function Auth() {
>
{t('authActivateProjectButton')}
</Button>

<ul>
{tests.isSuccess &&
tests.data.map((test) => (
<li key={test.id}>
{test.id}{' '}
<Button variant="ghost" onClick={() => deleteTest(test)}>
<X />
</Button>
</li>
))}
</ul>
{tests.isSuccess && tests.data.length > 0 && (
<Link to={'../'}>Go to notebooks</Link>
)}
</div>
</>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const Onboarding = () => {
<p>{t('description3')}</p>
<Button data-testid="create-notebook-link" asChild>
<Link
to="new"
to="../new"
className="hover:no-underline hover:text-primary-foreground"
>
{t('createNotebookButton')}
Expand Down
Loading

0 comments on commit cc6df1b

Please sign in to comment.