diff --git a/package-lock.json b/package-lock.json index b627491..d5a5d1d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "2.0.0-rc.2", "dependencies": { "@maany_shr/kernel-planckster-sdk-ts": "^2.0.0-alpha", - "@maany_shr/rage-ui-kit": "^1.1.1", + "@maany_shr/rage-ui-kit": "^1.1.2", "@preact/signals-react": "^2.1.0", "@tanstack/react-query": "^5.25.0", "@tanstack/react-query-devtools": "^5.51.21", @@ -1673,9 +1673,9 @@ } }, "node_modules/@maany_shr/rage-ui-kit": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@maany_shr/rage-ui-kit/-/rage-ui-kit-1.1.1.tgz", - "integrity": "sha512-n1qrUZsjS6sMFWXyikYjfpROYHhdbl7q53nVnz9qh8M+wJxbVW1jcicYYTk54S6itpYGg7kP8GzHeImVYSDWKg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@maany_shr/rage-ui-kit/-/rage-ui-kit-1.1.2.tgz", + "integrity": "sha512-+cuCSBB8gocsVq5M0/qMOK2zh1a1uTnFwfNgvoOfde49J24HtqWuVyBE3MzKQmhdY5nU82NMV2VcF0ahq7USZg==", "dependencies": { "@heroicons/react": "^2.1.3", "@hookform/resolvers": "^3.4.2", diff --git a/package.json b/package.json index 276c6df..82f4234 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ }, "dependencies": { "@maany_shr/kernel-planckster-sdk-ts": "^2.0.0-alpha", - "@maany_shr/rage-ui-kit": "^1.1.1", + "@maany_shr/rage-ui-kit": "^1.1.2", "@preact/signals-react": "^2.1.0", "@tanstack/react-query": "^5.25.0", "@tanstack/react-query-devtools": "^5.51.21", diff --git a/src/app/[rc_id]/conversations/page.tsx b/src/app/[rc_id]/conversations/page.tsx index 9272349..0d1dfdc 100644 --- a/src/app/[rc_id]/conversations/page.tsx +++ b/src/app/[rc_id]/conversations/page.tsx @@ -9,7 +9,6 @@ import type { Signal } from "~/lib/core/entity/signals"; import signalsContainer from "~/lib/infrastructure/common/signals-container"; import { SIGNAL_FACTORY } from "~/lib/infrastructure/common/signals-ioc-container"; import type { TListConversationsControllerParameters } from "~/lib/infrastructure/server/controller/list-conversations-controller"; -import { Suspense } from "react"; export default async function ListConversationsServerPage({ params }: { params: { rc_id: string } }) { const researchContextID = parseInt(params.rc_id); @@ -36,9 +35,5 @@ export default async function ListConversationsServerPage({ params }: { params: await controller.execute(controllerParameters); - return ( - AG GRID SKELETON...}> - - - ); + return ; } diff --git a/src/app/[rc_id]/sources/page.tsx b/src/app/[rc_id]/sources/page.tsx index 578e600..c2d35e4 100755 --- a/src/app/[rc_id]/sources/page.tsx +++ b/src/app/[rc_id]/sources/page.tsx @@ -3,7 +3,7 @@ import type AuthGatewayOutputPort from "~/lib/core/ports/secondary/auth-gateway- import serverContainer from "~/lib/infrastructure/server/config/ioc/server-container"; import { CONTROLLERS, GATEWAYS } from "~/lib/infrastructure/server/config/ioc/server-ioc-symbols"; import { ListSourceDataForResearchContextClientPage } from "../../_components/list-source-data-research-context"; -import {type TListSourceDataControllerParameters} from "~/lib/infrastructure/server/controller/list-source-data-controller"; +import { type TListSourceDataControllerParameters } from "~/lib/infrastructure/server/controller/list-source-data-controller"; import type ListSourceDataController from "~/lib/infrastructure/server/controller/list-source-data-controller"; import signalsContainer from "~/lib/infrastructure/common/signals-container"; import { type TListSourceDataViewModel } from "~/lib/core/view-models/list-source-data-view-models"; @@ -11,10 +11,7 @@ import type { Signal } from "~/lib/core/entity/signals"; import { SIGNAL_FACTORY } from "~/lib/infrastructure/common/signals-ioc-container"; import { Suspense } from "react"; - -export default async function ListSourceDataForResearchContextServerPage( - { params }: { params: { rc_id: string } } -) { +export default async function ListSourceDataForResearchContextServerPage({ params }: { params: { rc_id: string } }) { const authGateway = serverContainer.get(GATEWAYS.AUTH_GATEWAY); const sessionDTO = await authGateway.getSession(); if (!sessionDTO.success) { @@ -38,14 +35,5 @@ export default async function ListSourceDataForResearchContextServerPage( await controller.execute(controllerParameters); - return ( - <> - AG GRID SKELETON...}> - - - - ); -} \ No newline at end of file + return ; +} diff --git a/src/app/_components/layouts/page-layout.tsx b/src/app/_components/layouts/page-layout.tsx index 5be0202..6a8ca41 100644 --- a/src/app/_components/layouts/page-layout.tsx +++ b/src/app/_components/layouts/page-layout.tsx @@ -1,6 +1,5 @@ "use client" -import { Header } from "@maany_shr/rage-ui-kit" -import { SiteFooter } from "@maany_shr/rage-ui-kit" +import {Header, Toaster, SiteFooter} from "@maany_shr/rage-ui-kit" import Link from "next/link"; export const PageLayout = (props: {children: React.ReactNode}) =>{ @@ -20,6 +19,8 @@ export const PageLayout = (props: {children: React.ReactNode}) =>{ {props.children} + + {/* Footer */} diff --git a/src/app/_components/list-conversations.tsx b/src/app/_components/list-conversations.tsx index 159121d..7c1724f 100644 --- a/src/app/_components/list-conversations.tsx +++ b/src/app/_components/list-conversations.tsx @@ -1,24 +1,15 @@ "use client"; import { type TListConversationsViewModel } from "~/lib/core/view-models/list-conversations-view-model"; -import { useState } from "react"; -import signalsContainer from "~/lib/infrastructure/common/signals-container"; +import { useEffect, useState } from "react"; import type { Signal } from "~/lib/core/entity/signals"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; -import { SIGNAL_FACTORY } from "~/lib/infrastructure/common/signals-ioc-container"; -import clientContainer from "~/lib/infrastructure/client/config/ioc/client-container"; -import { CONTROLLERS } from "~/lib/infrastructure/client/config/ioc/client-ioc-symbols"; -import type BrowserListConversationsController from "~/lib/infrastructure/client/controller/browser-list-conversations-controller"; -import type { TBrowserListConversationsControllerParameters } from "~/lib/infrastructure/client/controller/browser-list-conversations-controller"; import type { TCreateConversationViewModel } from "~/lib/core/view-models/create-conversation-view-model"; -import type BrowserCreateConversationController from "~/lib/infrastructure/client/controller/browser-create-conversation-controller"; -import type { TBrowserCreateConversationControllerParameters } from "~/lib/infrastructure/client/controller/browser-create-conversation-controller"; -import { ConversationAGGrid } from '@maany_shr/rage-ui-kit'; -import { useRouter } from "next/navigation"; +import { ConversationAGGrid, useToast } from "@maany_shr/rage-ui-kit"; import { type ConversationRow } from "node_modules/@maany_shr/rage-ui-kit/dist/components/table/ConversationAGGrid"; - +import { useRouter } from "next/navigation"; +import { createConversationMutation, DEFAULT_RETRIES, DEFAULT_RETRY_DELAY, queryConversations } from "~/app/queries"; export function ListConversationsClientPage(props: { viewModel: TListConversationsViewModel; researchContextID: number }) { - const [listConversationsViewModel, setListConversationsViewModel] = useState(props.viewModel); const [createConversationViewModel, setCreateConversationViewModel] = useState({ @@ -27,84 +18,62 @@ export function ListConversationsClientPage(props: { viewModel: TListConversatio const queryClient = useQueryClient(); - const { isFetching, isLoading, isError } = useQuery>({ + useQuery>({ queryKey: [`list-conversations#${props.researchContextID}`], - queryFn: async () => { - const signalFactory = signalsContainer.get<(initialValue: TListConversationsViewModel, update?: (value: TListConversationsViewModel) => void) => Signal>(SIGNAL_FACTORY.KERNEL_LIST_CONVERSATIONS); - const response: Signal = signalFactory( - { - status: "request", - }, - setListConversationsViewModel, - ); - const controllerParameters: TBrowserListConversationsControllerParameters = { - response: response, - researchContextID: props.researchContextID, - }; - const controller = clientContainer.get(CONTROLLERS.LIST_CONVERSATIONS_CONTROLLER); - await controller.execute(controllerParameters); - return response; - }, + queryFn: queryConversations(setListConversationsViewModel, props.researchContextID), }); - const enableCreateConversation = !isFetching || !isLoading; - const mutation = useMutation({ mutationKey: ["create-conversation"], - retry: 3, - retryDelay: 3000, - onSuccess: async (data) => { - await queryClient.invalidateQueries({queryKey: [`list-conversations#${props.researchContextID}`]}); - }, - mutationFn: async (title: string) => { - const signalFactory = signalsContainer.get<(initialValue: TCreateConversationViewModel, update?: (value: TCreateConversationViewModel) => void) => Signal>(SIGNAL_FACTORY.KERNEL_CREATE_CONVERSATION); - const response: Signal = signalFactory( - { - status: "request", - } as TCreateConversationViewModel, - setCreateConversationViewModel, - ); - const controller = clientContainer.get(CONTROLLERS.CREATE_CONVERSATION_CONTROLLER); - const controllerParameters: TBrowserCreateConversationControllerParameters = { - response: response, - researchContextID: props.researchContextID, - title: title, - }; - await controller.execute(controllerParameters); + retry: DEFAULT_RETRIES, + retryDelay: DEFAULT_RETRY_DELAY, + onSuccess: async () => { + await queryClient.invalidateQueries({ queryKey: [`list-conversations#${props.researchContextID}`] }); }, + mutationFn: createConversationMutation(setCreateConversationViewModel), }); const handleCreateConversation = (title: string) => { - console.log("Creating conversation with title: ", title); - mutation.mutate(title); + mutation.mutate({ title, researchContextID: props.researchContextID }); }; const router = useRouter(); const handleGoToConversation = (conversationID: number) => { - console.log("Going to conversation with ID: ", conversationID); router.push(`conversations/${conversationID}`); - } + }; + + const { toast } = useToast(); - if (listConversationsViewModel.status === "success") { - return ; - } else { - return { + if (createConversationViewModel.status === "error") { + toast({ + title: "Error creating the conversation", + description: createConversationViewModel.message, + variant: "error", + }); + } + }, [createConversationViewModel]); + + const areConversationsLoading = listConversationsViewModel.status === "request"; + const rowData = listConversationsViewModel.status === "success" ? listConversationsViewModel.conversations : []; + const errorOverlayProperties = + listConversationsViewModel.status === "error" + ? { errorStatus: true, - overlayText: `Error: ${JSON.stringify(listConversationsViewModel)}`, - }} - />; - } + overlayText: listConversationsViewModel.message, + } + : undefined; + + // TODO: fix the typing issue without additional imports + return ( + + ); } diff --git a/src/app/_components/list-source-data-client.tsx b/src/app/_components/list-source-data-client.tsx index 1616382..74cd4f6 100755 --- a/src/app/_components/list-source-data-client.tsx +++ b/src/app/_components/list-source-data-client.tsx @@ -1,22 +1,13 @@ "use client"; -import { SourceDataAGGrid } from "@maany_shr/rage-ui-kit"; +import { SourceDataAGGrid, useToast } from "@maany_shr/rage-ui-kit"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; -import { useRef, useState } from "react"; +import { useEffect, useRef, useState } from "react"; import { type Signal } from "~/lib/core/entity/signals"; import { type TFileDownloadViewModel } from "~/lib/core/view-models/file-download-view-model"; import { type TFileUploadViewModel } from "~/lib/core/view-models/file-upload-view-model"; import { type TListSourceDataViewModel } from "~/lib/core/view-models/list-source-data-view-models"; -import clientContainer from "~/lib/infrastructure/client/config/ioc/client-container"; -import { CONTROLLERS } from "~/lib/infrastructure/client/config/ioc/client-ioc-symbols"; -import { type TBrowserFileDownloadControllerParameters } from "~/lib/infrastructure/client/controller/browser-file-download-controller"; -import type BrowserFileDownloadController from "~/lib/infrastructure/client/controller/browser-file-download-controller"; -import { type TBrowserFileUploadControllerParameters } from "~/lib/infrastructure/client/controller/browser-file-upload-controller"; -import type BrowserFileUploadController from "~/lib/infrastructure/client/controller/browser-file-upload-controller"; -import { type TBrowserListSourceDataControllerParameters } from "~/lib/infrastructure/client/controller/browser-list-source-data-controller"; -import type BrowserListSourceDataController from "~/lib/infrastructure/client/controller/browser-list-source-data-controller"; -import signalsContainer from "~/lib/infrastructure/common/signals-container"; -import { SIGNAL_FACTORY } from "~/lib/infrastructure/common/signals-ioc-container"; +import { DEFAULT_RETRIES, DEFAULT_RETRY_DELAY, downloadSourceMutation, querySources, uploadSourceMutation } from "~/app/queries"; export function ListSourceDataForClientClientPage(props: { viewModel: TListSourceDataViewModel; clientID: string }) { const [uploadSourceDataViewModel, setUploadSourceDataViewModel] = useState({ @@ -31,116 +22,96 @@ export function ListSourceDataForClientClientPage(props: { viewModel: TListSourc const queryClient = useQueryClient(); - const { isFetching, isLoading, isError } = useQuery>({ + useQuery>({ queryKey: ["list-source-data"], - queryFn: async () => { - const signalFactory = signalsContainer.get<(initialValue: TListSourceDataViewModel, update?: (value: TListSourceDataViewModel) => void) => Signal>(SIGNAL_FACTORY.KERNEL_LIST_SOURCE_DATA); - const response: Signal = signalFactory( - { - status: "request", - }, - setListSourceDataViewModel, - ); - const controllerParameters: TBrowserListSourceDataControllerParameters = { - response: response, - }; - const controller = clientContainer.get(CONTROLLERS.LIST_SOURCE_DATA_CONTROLLER); - await controller.execute(controllerParameters); - return response; - }, + queryFn: querySources(setListSourceDataViewModel), }); const downloadMutation = useMutation({ mutationKey: ["download-source-data"], - retry: 3, - retryDelay: 3000, - mutationFn: async (params: { relativePath: string; sourceDataName: string }) => { - const signalFactory = signalsContainer.get<(initialValue: TFileDownloadViewModel, update?: (value: TFileDownloadViewModel) => void) => Signal>(SIGNAL_FACTORY.KERNEL_FILE_DOWNLOAD); - const response: Signal = signalFactory( - { - status: "request", - } as TFileDownloadViewModel, - setDownloadSourceDataViewModel, - ); - const controllerParameters: TBrowserFileDownloadControllerParameters = { - response: response, - relativePath: params.relativePath, - localPath: params.sourceDataName, - }; - const controller = clientContainer.get(CONTROLLERS.KERNEL_FILE_DOWNLOAD_CONTROLLER); - await controller.execute(controllerParameters); - return response; - }, + retry: DEFAULT_RETRIES, + retryDelay: DEFAULT_RETRY_DELAY, + mutationFn: downloadSourceMutation(setDownloadSourceDataViewModel), }); const uploadMutation = useMutation({ mutationKey: ["upload-source-data"], - retry: 3, - retryDelay: 3000, - onSuccess: async (data) => { + retry: DEFAULT_RETRIES, + retryDelay: DEFAULT_RETRY_DELAY, + onSuccess: async () => { await queryClient.invalidateQueries({ queryKey: ["list-source-data"] }); }, - mutationFn: async (file: File) => { - const signalFactory = signalsContainer.get<(initialValue: TFileUploadViewModel, update?: (value: TFileUploadViewModel) => void) => Signal>(SIGNAL_FACTORY.KERNEL_FILE_UPLOAD); - const response: Signal = signalFactory( - { - status: "request", - } as TFileUploadViewModel, - setUploadSourceDataViewModel, - ); - const controllerParameters: TBrowserFileUploadControllerParameters = { - response: response, - file: file, - clientID: props.clientID, - }; - const controller = clientContainer.get(CONTROLLERS.KERNEL_FILE_UPLOAD_CONTROLLER); - await controller.execute(controllerParameters); - return response; - }, + mutationFn: uploadSourceMutation(setUploadSourceDataViewModel), }); const handleDownloadSourceData = (name: string, relativePath: string) => { - console.log("Download source data", relativePath, name); - downloadMutation.mutate({ relativePath: relativePath, sourceDataName: name }); + downloadMutation.mutate({ relativePath: relativePath, sourceFilename: name }); }; const fileInputRef = useRef(null); const handleUploadSourceData = () => { - console.log("Upload source data"); if (fileInputRef.current) { fileInputRef.current.click(); } }; const handleFileChange = (event: React.ChangeEvent) => { - if (event.target.files?.[0]) { - const file = event.target.files[0]; - - if (!file) { - return; + const file = event.target.files?.[0]; + if (file) { + // Reset the input's state to enable repeated upload + if (fileInputRef.current) { + fileInputRef.current.value = ""; } - - uploadMutation.mutate(file); + uploadMutation.mutate({ file, clientID: props.clientID }); } }; - const isUploading = uploadMutation.isPending; + const { toast } = useToast(); - // TODO: decompose without if statements - if (listSourceDataViewModel.status === "request") { - return ( - <> - - - ); - } else if (listSourceDataViewModel.status === "success") { - return ( - <> - - - - - ); - } + useEffect(() => { + if (uploadSourceDataViewModel.status === "error") { + toast({ + title: "Error uploading the file", + description: uploadSourceDataViewModel.message, + variant: "error", + }); + } + }, [uploadSourceDataViewModel]); + + useEffect(() => { + if (downloadSourceDataViewModel.status === "error") { + toast({ + title: "Error downloading the file", + description: downloadSourceDataViewModel.message, + variant: "error", + }); + } + }, [downloadSourceDataViewModel]); + + const isUploading = uploadMutation.isPending; + const areSourcesLoading = listSourceDataViewModel.status === "request"; + const rowData = listSourceDataViewModel.status === "success" ? listSourceDataViewModel.sourceData : []; + const errorOverlayProperties = + listSourceDataViewModel.status === "error" + ? { + errorStatus: true, + overlayText: listSourceDataViewModel.message, + } + : undefined; + + return ( + <> + + + + ); } diff --git a/src/app/_components/list-source-data-research-context.tsx b/src/app/_components/list-source-data-research-context.tsx index 8d4cc29..3fb9635 100755 --- a/src/app/_components/list-source-data-research-context.tsx +++ b/src/app/_components/list-source-data-research-context.tsx @@ -1,85 +1,62 @@ "use client"; -import { SourceDataAGGrid } from "@maany_shr/rage-ui-kit"; +import { SourceDataAGGrid, useToast } from "@maany_shr/rage-ui-kit"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; -import { useState } from "react"; +import { useEffect, useState } from "react"; import { type Signal } from "~/lib/core/entity/signals"; import { type TFileDownloadViewModel } from "~/lib/core/view-models/file-download-view-model"; import { type TListSourceDataViewModel } from "~/lib/core/view-models/list-source-data-view-models"; -import clientContainer from "~/lib/infrastructure/client/config/ioc/client-container"; -import { CONTROLLERS } from "~/lib/infrastructure/client/config/ioc/client-ioc-symbols"; -import {type TBrowserFileDownloadControllerParameters} from "~/lib/infrastructure/client/controller/browser-file-download-controller"; -import type BrowserFileDownloadController from "~/lib/infrastructure/client/controller/browser-file-download-controller"; -import {type TBrowserListSourceDataControllerParameters} from "~/lib/infrastructure/client/controller/browser-list-source-data-controller"; -import type BrowserListSourceDataController from "~/lib/infrastructure/client/controller/browser-list-source-data-controller"; -import signalsContainer from "~/lib/infrastructure/common/signals-container"; -import { SIGNAL_FACTORY } from "~/lib/infrastructure/common/signals-ioc-container"; - -export function ListSourceDataForResearchContextClientPage( - props: { viewModel: TListSourceDataViewModel; researchContextID: number }, -) { +import { DEFAULT_RETRIES, DEFAULT_RETRY_DELAY, downloadSourceMutation, querySources } from "~/app/queries"; +export function ListSourceDataForResearchContextClientPage(props: { viewModel: TListSourceDataViewModel; researchContextID: number }) { const [downloadSourceDataViewModel, setDownloadSourceDataViewModel] = useState({ status: "request", } as TFileDownloadViewModel); const [listSourceDataViewModel, setListSourceDataViewModel] = useState(props.viewModel); - const queryClient = useQueryClient(); + useQueryClient(); - const { isFetching, isLoading, isError } = useQuery>({ + useQuery>({ queryKey: [`list-source-data#${props.researchContextID}`], - queryFn: async () => { - const signalFactory = signalsContainer.get<(initialValue: TListSourceDataViewModel, update?: (value: TListSourceDataViewModel) => void) => Signal>(SIGNAL_FACTORY.KERNEL_LIST_SOURCE_DATA); - const response: Signal = signalFactory( - { - status: "request", - }, - setListSourceDataViewModel, - ); - const controllerParameters: TBrowserListSourceDataControllerParameters = { - response: response, - researchContextID: props.researchContextID, - }; - const controller = clientContainer.get(CONTROLLERS.LIST_SOURCE_DATA_CONTROLLER); - await controller.execute(controllerParameters); - return response; - }, + queryFn: querySources(setListSourceDataViewModel, props.researchContextID), }); const downloadMutation = useMutation({ mutationKey: ["download-source-data"], - retry: 3, - retryDelay: 3000, - mutationFn: async (params: {relativePath: string, sourceDataName: string}) => { - const signalFactory = signalsContainer.get<(initialValue: TFileDownloadViewModel, update?: (value: TFileDownloadViewModel) => void) => Signal>(SIGNAL_FACTORY.KERNEL_FILE_DOWNLOAD); - const response: Signal = signalFactory( - { - status: "request", - } as TFileDownloadViewModel, - setDownloadSourceDataViewModel, - ); - const controllerParameters: TBrowserFileDownloadControllerParameters = { - response: response, - relativePath: params.relativePath, - localPath: params.sourceDataName, - }; - const controller = clientContainer.get(CONTROLLERS.KERNEL_FILE_DOWNLOAD_CONTROLLER); - await controller.execute(controllerParameters); - return response; - }, + retry: DEFAULT_RETRIES, + retryDelay: DEFAULT_RETRY_DELAY, + mutationFn: downloadSourceMutation(setDownloadSourceDataViewModel), }); const handleDownloadSourceData = (name: string, relativePath: string) => { - console.log("Download source data", relativePath, name); - downloadMutation.mutate({relativePath: relativePath, sourceDataName: name}); + downloadMutation.mutate({ relativePath: relativePath, sourceFilename: name }); }; - const handleUploadSourceData: () => void = () => {console.log("")}; + const { toast } = useToast(); + + useEffect(() => { + if (downloadSourceDataViewModel.status === "error") { + toast({ + title: "Error downloading the file", + description: downloadSourceDataViewModel.message, + variant: "error", + }); + } + }, [downloadSourceDataViewModel]); const isSourceDataLoading = listSourceDataViewModel.status === "request"; const sourceData = listSourceDataViewModel.status === "success" ? listSourceDataViewModel.sourceData : []; + const errorOverlayProperties = + listSourceDataViewModel.status === "error" + ? { + errorStatus: true, + overlayText: listSourceDataViewModel.message, + } + : undefined; + return ( - + // eslint-disable-next-line @typescript-eslint/no-empty-function + {}} errorOverlayProps={errorOverlayProperties} /> ); } diff --git a/src/app/layout.tsx b/src/app/layout.tsx index b02d8b5..8c1538f 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -19,20 +19,12 @@ export const metadata = { icons: [{ rel: "icon", url: "/satellite.svg" }], }; -export default function RootLayout({ - children, -}: { - children: React.ReactNode; -}) { +export default function RootLayout({ children }: { children: React.ReactNode }) { return ( - - - {children} - - + {children} diff --git a/src/app/queries.ts b/src/app/queries.ts new file mode 100644 index 0000000..7ff7088 --- /dev/null +++ b/src/app/queries.ts @@ -0,0 +1,123 @@ +import signalsContainer from "~/lib/infrastructure/common/signals-container"; +import type { TListSourceDataViewModel } from "~/lib/core/view-models/list-source-data-view-models"; +import type { Signal } from "~/lib/core/entity/signals"; +import { SIGNAL_FACTORY } from "~/lib/infrastructure/common/signals-ioc-container"; +import clientContainer from "~/lib/infrastructure/client/config/ioc/client-container"; +import { CONTROLLERS } from "~/lib/infrastructure/client/config/ioc/client-ioc-symbols"; +import type { TFileDownloadViewModel } from "~/lib/core/view-models/file-download-view-model"; +import type { TFileUploadViewModel } from "~/lib/core/view-models/file-upload-view-model"; +import { Dispatch, SetStateAction } from "react"; +import BrowserListSourceDataController, { TBrowserListSourceDataControllerParameters } from "~/lib/infrastructure/client/controller/browser-list-source-data-controller"; +import BrowserFileDownloadController, { TBrowserFileDownloadControllerParameters } from "~/lib/infrastructure/client/controller/browser-file-download-controller"; +import BrowserFileUploadController, { TBrowserFileUploadControllerParameters } from "~/lib/infrastructure/client/controller/browser-file-upload-controller"; +import type { TListConversationsViewModel } from "~/lib/core/view-models/list-conversations-view-model"; +import BrowserListConversationsController, { TBrowserListConversationsControllerParameters } from "~/lib/infrastructure/client/controller/browser-list-conversations-controller"; +import type { TCreateConversationViewModel } from "~/lib/core/view-models/create-conversation-view-model"; +import BrowserCreateConversationController, { TBrowserCreateConversationControllerParameters } from "~/lib/infrastructure/client/controller/browser-create-conversation-controller"; + +export const DEFAULT_RETRIES = 3; +export const DEFAULT_RETRY_DELAY = 3000; + +const querySources = (setListSourceDataViewModel: Dispatch>, researchContextID?: number) => async () => { + const signalFactory = signalsContainer.get<(initialValue: TListSourceDataViewModel, update?: (value: TListSourceDataViewModel) => void) => Signal>(SIGNAL_FACTORY.KERNEL_LIST_SOURCE_DATA); + const response: Signal = signalFactory( + { + status: "request", + }, + setListSourceDataViewModel, + ); + const controllerParameters: TBrowserListSourceDataControllerParameters = { + response: response, + researchContextID: researchContextID, + }; + const controller = clientContainer.get(CONTROLLERS.LIST_SOURCE_DATA_CONTROLLER); + await controller.execute(controllerParameters); + return response; +}; + +type DownloadSourceMutationParams = { + relativePath: string; + sourceFilename: string; +}; + +const downloadSourceMutation = (setDownloadSourceDataViewModel: Dispatch>) => async (params: DownloadSourceMutationParams) => { + const signalFactory = signalsContainer.get<(initialValue: TFileDownloadViewModel, update?: (value: TFileDownloadViewModel) => void) => Signal>(SIGNAL_FACTORY.KERNEL_FILE_DOWNLOAD); + const response: Signal = signalFactory( + { + status: "request", + } as TFileDownloadViewModel, + setDownloadSourceDataViewModel, + ); + const controllerParameters: TBrowserFileDownloadControllerParameters = { + response: response, + relativePath: params.relativePath, + localPath: params.sourceFilename, + }; + const controller = clientContainer.get(CONTROLLERS.KERNEL_FILE_DOWNLOAD_CONTROLLER); + await controller.execute(controllerParameters); + return response; +}; + +type UploadSourceMutationParams = { + file: File; + clientID: string; +}; + +const uploadSourceMutation = (setUploadSourceDataViewModel: Dispatch>) => async (params: UploadSourceMutationParams) => { + const signalFactory = signalsContainer.get<(initialValue: TFileUploadViewModel, update?: (value: TFileUploadViewModel) => void) => Signal>(SIGNAL_FACTORY.KERNEL_FILE_UPLOAD); + const response: Signal = signalFactory( + { + status: "request", + } as TFileUploadViewModel, + setUploadSourceDataViewModel, + ); + const controllerParameters: TBrowserFileUploadControllerParameters = { + response: response, + file: params.file, + clientID: params.clientID, + }; + const controller = clientContainer.get(CONTROLLERS.KERNEL_FILE_UPLOAD_CONTROLLER); + await controller.execute(controllerParameters); + return response; +}; + +const queryConversations = (setListConversationsViewModel: Dispatch>, researchContextID: number) => async () => { + const signalFactory = signalsContainer.get<(initialValue: TListConversationsViewModel, update?: (value: TListConversationsViewModel) => void) => Signal>(SIGNAL_FACTORY.KERNEL_LIST_CONVERSATIONS); + const response: Signal = signalFactory( + { + status: "request", + }, + setListConversationsViewModel, + ); + const controllerParameters: TBrowserListConversationsControllerParameters = { + response: response, + researchContextID: researchContextID, + }; + const controller = clientContainer.get(CONTROLLERS.LIST_CONVERSATIONS_CONTROLLER); + await controller.execute(controllerParameters); + return response; +}; + +type CreateConversationMutationParams = { + title: string; + researchContextID: number; +}; + +const createConversationMutation = (setCreateConversationViewModel: Dispatch>) => async (params: CreateConversationMutationParams) => { + const signalFactory = signalsContainer.get<(initialValue: TCreateConversationViewModel, update?: (value: TCreateConversationViewModel) => void) => Signal>(SIGNAL_FACTORY.KERNEL_CREATE_CONVERSATION); + const response: Signal = signalFactory( + { + status: "request", + } as TCreateConversationViewModel, + setCreateConversationViewModel, + ); + const controller = clientContainer.get(CONTROLLERS.CREATE_CONVERSATION_CONTROLLER); + const controllerParameters: TBrowserCreateConversationControllerParameters = { + response: response, + researchContextID: params.researchContextID, + title: params.title, + }; + await controller.execute(controllerParameters); +}; + +export { querySources, downloadSourceMutation, uploadSourceMutation, queryConversations, createConversationMutation }; diff --git a/src/app/sources/page.tsx b/src/app/sources/page.tsx index 65d2a77..1732614 100755 --- a/src/app/sources/page.tsx +++ b/src/app/sources/page.tsx @@ -3,13 +3,12 @@ import type AuthGatewayOutputPort from "~/lib/core/ports/secondary/auth-gateway- import serverContainer from "~/lib/infrastructure/server/config/ioc/server-container"; import { CONTROLLERS, GATEWAYS } from "~/lib/infrastructure/server/config/ioc/server-ioc-symbols"; import { ListSourceDataForClientClientPage } from "../_components/list-source-data-client"; -import {type TListSourceDataControllerParameters} from "~/lib/infrastructure/server/controller/list-source-data-controller"; +import { type TListSourceDataControllerParameters } from "~/lib/infrastructure/server/controller/list-source-data-controller"; import type ListSourceDataController from "~/lib/infrastructure/server/controller/list-source-data-controller"; import signalsContainer from "~/lib/infrastructure/common/signals-container"; import { type TListSourceDataViewModel } from "~/lib/core/view-models/list-source-data-view-models"; import type { Signal } from "~/lib/core/entity/signals"; import { SIGNAL_FACTORY } from "~/lib/infrastructure/common/signals-ioc-container"; -import { Suspense } from "react"; export default async function ListSourceDataForClientServerPage() { const authGateway = serverContainer.get(GATEWAYS.AUTH_GATEWAY); @@ -18,7 +17,7 @@ export default async function ListSourceDataForClientServerPage() { redirect("/auth/login"); } - const clientID = sessionDTO.data.user.id + const clientID = sessionDTO.data.user.id; // Initialize the source data to show const controller = serverContainer.get(CONTROLLERS.LIST_SOURCE_DATA_CONTROLLER); @@ -35,11 +34,5 @@ export default async function ListSourceDataForClientServerPage() { await controller.execute(controllerParameters); - return ( -
- AG GRID SKELETON...
}> - - - - ); + return ; }