Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance and refactor table views #67

Merged
merged 23 commits into from
Nov 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
825fd0b
Update UI kit version
MytsV Nov 8, 2024
0f671e3
Remove an unneeded suspense in the all sources view
MytsV Nov 8, 2024
e79e1fd
Refactor a confusing if statement
MytsV Nov 8, 2024
20e2673
Improve readability of all sources queries
MytsV Nov 8, 2024
74e1f7d
Remove unnecessary logging
MytsV Nov 8, 2024
b13e7a2
Reformat the all source data view
MytsV Nov 8, 2024
35ff9fe
Add a toast provider to the layout
MytsV Nov 8, 2024
cc3bf85
Implement toasts on upload errors
MytsV Nov 8, 2024
8df1d4f
Implement toasts on download errors
MytsV Nov 8, 2024
b66c550
Implement toasts on source data fetching errors
MytsV Nov 8, 2024
db09d6d
Enable repeated upload of the same file
MytsV Nov 8, 2024
7dd7ec5
Remove unnecessary wrapper for the sources page
MytsV Nov 8, 2024
84ae73a
Remove suspense for the RC-sources page
MytsV Nov 8, 2024
4b691e7
Decompose sources queries into a different file
MytsV Nov 8, 2024
442bec3
Set default retry parameters as an app-wide constant
MytsV Nov 8, 2024
4721fa1
Add error handling via toasts to the RC sources view
MytsV Nov 8, 2024
6237ef3
Remove unnecessary suspense on the conversations page
MytsV Nov 8, 2024
8573b87
Display error overlay in sources lists
MytsV Nov 8, 2024
4c14172
Decompose queries from conversation list
MytsV Nov 8, 2024
536b586
Remove redundant logging
MytsV Nov 8, 2024
fbb4c05
Implement toasts on create new conversation error
MytsV Nov 8, 2024
4eb252d
Remove bulky if statement from list conversations
MytsV Nov 8, 2024
a633ec8
Update package-lock.json and an incorrect import
MytsV Nov 8, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
7 changes: 1 addition & 6 deletions src/app/[rc_id]/conversations/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -36,9 +35,5 @@ export default async function ListConversationsServerPage({ params }: { params:

await controller.execute(controllerParameters);

return (
<Suspense fallback={<div>AG GRID SKELETON...</div>}>
<ListConversationsClientPage viewModel={response.value} researchContextID={researchContextID}/>
</Suspense>
);
return <ListConversationsClientPage viewModel={response.value} researchContextID={researchContextID} />;
}
20 changes: 4 additions & 16 deletions src/app/[rc_id]/sources/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,15 @@ 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";
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<AuthGatewayOutputPort>(GATEWAYS.AUTH_GATEWAY);
const sessionDTO = await authGateway.getSession();
if (!sessionDTO.success) {
Expand All @@ -38,14 +35,5 @@ export default async function ListSourceDataForResearchContextServerPage(

await controller.execute(controllerParameters);

return (
<>
<Suspense fallback={<div>AG GRID SKELETON...</div>}>
<ListSourceDataForResearchContextClientPage
viewModel={response.value}
researchContextID={researchContextID}
/>
</Suspense>
</>
);
}
return <ListSourceDataForResearchContextClientPage viewModel={response.value} researchContextID={researchContextID} />;
}
5 changes: 3 additions & 2 deletions src/app/_components/layouts/page-layout.tsx
Original file line number Diff line number Diff line change
@@ -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}) =>{
Expand All @@ -20,6 +19,8 @@ export const PageLayout = (props: {children: React.ReactNode}) =>{
{props.children}
</main>

<Toaster/>

{/* Footer */}
<SiteFooter />
</div>
Expand Down
121 changes: 45 additions & 76 deletions src/app/_components/list-conversations.tsx
Original file line number Diff line number Diff line change
@@ -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<TListConversationsViewModel>(props.viewModel);

const [createConversationViewModel, setCreateConversationViewModel] = useState<TCreateConversationViewModel>({
Expand All @@ -27,84 +18,62 @@ export function ListConversationsClientPage(props: { viewModel: TListConversatio

const queryClient = useQueryClient();

const { isFetching, isLoading, isError } = useQuery<Signal<TListConversationsViewModel>>({
useQuery<Signal<TListConversationsViewModel>>({
queryKey: [`list-conversations#${props.researchContextID}`],
queryFn: async () => {
const signalFactory = signalsContainer.get<(initialValue: TListConversationsViewModel, update?: (value: TListConversationsViewModel) => void) => Signal<TListConversationsViewModel>>(SIGNAL_FACTORY.KERNEL_LIST_CONVERSATIONS);
const response: Signal<TListConversationsViewModel> = signalFactory(
{
status: "request",
},
setListConversationsViewModel,
);
const controllerParameters: TBrowserListConversationsControllerParameters = {
response: response,
researchContextID: props.researchContextID,
};
const controller = clientContainer.get<BrowserListConversationsController>(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<TCreateConversationViewModel>>(SIGNAL_FACTORY.KERNEL_CREATE_CONVERSATION);
const response: Signal<TCreateConversationViewModel> = signalFactory(
{
status: "request",
} as TCreateConversationViewModel,
setCreateConversationViewModel,
);
const controller = clientContainer.get<BrowserCreateConversationController>(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 <ConversationAGGrid
isLoading={isFetching || isLoading}
rowData={listConversationsViewModel.conversations as ConversationRow[]}
handleGoToConversation={handleGoToConversation}
handleNewConversation={handleCreateConversation}
newConversationIsEnabled={enableCreateConversation}
/>;
} else {
return <ConversationAGGrid
isLoading={false}
rowData={[]}
handleGoToConversation={handleGoToConversation}
handleNewConversation={handleCreateConversation}
newConversationIsEnabled={enableCreateConversation}
errorOverlayProps={{
useEffect(() => {
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 (
<ConversationAGGrid
rowData={rowData as ConversationRow[]}
isLoading={areConversationsLoading}
newConversationIsEnabled={!areConversationsLoading}
handleGoToConversation={handleGoToConversation}
handleNewConversation={handleCreateConversation}
errorOverlayProps={errorOverlayProperties}
/>
);
}
Loading
Loading