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

[TSK-259] Easy features #18

Merged
merged 7 commits into from
Sep 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions lib/components/conversation/mermaid-message-content.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
"use client";
import mermaid from "mermaid";
import { ReactNode, useEffect } from "react";

Expand Down
22 changes: 19 additions & 3 deletions lib/components/dialog/CreateConversationDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,15 @@ import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import { z } from "zod";
import { PenSquare } from "lucide-react";
import { useState } from "react";

export interface buttonActionInputValues {
conversationTitle: string;
}

export interface CreateConversationDialogProps {
isEnabled: boolean;
isOpen?: boolean;
buttonAction: (inputValues: buttonActionInputValues) => void;
}

Expand All @@ -50,6 +53,8 @@ const formSchema = z.object({
* Create a new conversation dialog
*/
export const CreateConversationDialog = ({
isEnabled,
isOpen = false,
buttonAction,
...props
}: CreateConversationDialogProps) => {
Expand All @@ -61,13 +66,22 @@ export const CreateConversationDialog = ({
});

const onSubmitWrapper = (values: z.infer<typeof formSchema>) => {
setIsDialogOpen(false);
buttonAction(values);
};

const [isDialogOpen, setIsDialogOpen] = useState(isOpen);

return (
<ShadcnDialog {...props}>
<ShadcnDialog open={isDialogOpen} onOpenChange={setIsDialogOpen} {...props}>
<DialogTrigger asChild>
<Button variant="default" size="icon" label={<PenSquare />} />
<Button
variant="default"
size="icon"
label={<PenSquare />}
disabled={!isEnabled}
onClick={() => setIsDialogOpen(true)}
/>
</DialogTrigger>

<DialogContent
Expand All @@ -80,7 +94,9 @@ export const CreateConversationDialog = ({
"text-black dark:text-white",
)}
>
<DialogClose asChild />
<div onClick={() => setIsDialogOpen(false)}>
<DialogClose asChild />
</div>

<DialogHeader>
<DialogTitle>New conversation</DialogTitle>
Expand Down
4 changes: 2 additions & 2 deletions lib/components/table/BaseAGGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ export function BaseAGGrid<TRowData>({
<div
id="ag-grid-inner-component"
className={cn("ag-theme-sda h-screen overflow-auto")}
style={{ height: "80vh", width: "80vw" }}
style={{ height: "80vh", width: "100vw" }}
>
<AgGridReact
loading={isLoading}
Expand All @@ -294,7 +294,7 @@ export function BaseAGGrid<TRowData>({
<div
id="ag-grid-inner-component"
className={cn("ag-theme-sda h-screen overflow-auto")}
style={{ height: "80vh", width: "80vw" }}
style={{ height: "80vh", width: "100vw" }}
>
<AgGridReact
rowData={[]}
Expand Down
14 changes: 12 additions & 2 deletions lib/components/table/ConversationAGGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export type ConversationRow = z.infer<typeof ConversationRowSchema>;
export interface ConversationAGGridProps {
rowData: ConversationRow[];
isLoading: boolean;
newConversationIsEnabled: boolean;
handleGoToConversation: (id: number) => void;
handleNewConversation: (conversationTitle: string) => void;
errorOverlayProps?: {
Expand Down Expand Up @@ -61,14 +62,20 @@ const GoToConversationButton = (params: GoToConversationButtonParams) => {
};

const NewConversationComponent = (
isEnabled: boolean,
handleNewConversation: (title: string) => void,
) => {
// Wrapper to pass it as a buttonAction to the dialog
const newConversationAction = (inputValues: buttonActionInputValues) => {
handleNewConversation(inputValues.conversationTitle);
};

return <CreateConversationDialog buttonAction={newConversationAction} />;
return (
<CreateConversationDialog
isEnabled={isEnabled}
buttonAction={newConversationAction}
/>
);
};

/**
Expand Down Expand Up @@ -114,7 +121,10 @@ export function ConversationAGGrid(props: ConversationAGGridProps) {
rowData={props.rowData}
columnDefs={columnDefs}
additionalComponentsLeft={[
NewConversationComponent(props.handleNewConversation),
NewConversationComponent(
props.newConversationIsEnabled,
props.handleNewConversation,
),
]}
errorOverlayProps={props.errorOverlayProps}
// @ts-expect-error TODO: fix typing here somehow, passing "AGGridProps = { {context = ... } }" to "BaseAGGrid" doesn't work
Expand Down
107 changes: 107 additions & 0 deletions lib/components/table/SelectableSourceDataAGGrid.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
"use client";
import { z } from "zod";
import { BaseAGGrid } from "./BaseAGGrid";
import { ColDef } from "ag-grid-community";
import { useState } from "react";

import { Button as ShadcnButton } from "@/components/button/index";

const SourceDataRowSchema = z.object({
id: z.string(),
name: z.string(),
relativePath: z.string(),
createdAt: z.string(),
});

/**
* SourceDataRow is a type that represents the structure of the data that will be displayed in the AG Grid.
*/
export type SelectableSourceDataRow = z.infer<typeof SourceDataRowSchema>;

/**
* SourceDataAGGridProps is an interface that defines the props for the SourceDataAGGrid component.
* @param rowData: the data to be displayed in the AG Grid. Must be an array of SourceDataRow objects.
* @param buttonsWithCallBack: an array of objects containing a reactComponent and a callbackFunction.
*/
export interface SelectableSourceDataAGGridProps {
rowData: SelectableSourceDataRow[];
isLoading: boolean;
handleConfirmSelection: (selectedRows: SelectableSourceDataRow[]) => void;
errorOverlayProps?: {
errorStatus: boolean;
overlayText: string;
};
}

const ConfirmSelectionButton = ({ onClick }: { onClick: () => void }) => {
return (
<ShadcnButton
label={"Confirm Selection"}
variant="default"
onClick={onClick}
title="Confirm the selected rows"
/>
);
};

/**
* SourceDataAGGrid is a react component that displays a table of source data in an AG Grid.
* @param rowData: the data to be displayed in the AG Grid. Must be an array of SourceDataRow objects.
* @param handleDownloadSourceData: a function that is called when the download button is clicked.
* @param handleUploadSourceData: a function that is called when the upload button is clicked.
* @param isLoading: a boolean that indicates whether the data is still loading.
* @param errorOverlayProps: an object that contains the error status and overlay text.
* @returns a react component that displays a table of source data in an AG Grid.
*/
export function SelectableSourceDataAGGrid(
props: SelectableSourceDataAGGridProps,
) {
const [columnDefs] = useState<ColDef[]>([
{
headerCheckboxSelection: true,
headerCheckboxSelectionFilteredOnly: true,
checkboxSelection: true,
headerName: "ID",
filter: false,
field: "id",
flex: 0.3,
},
{
headerName: "Name",
field: "name",
flex: 1.5,
},
{
headerName: "Relative Path",
field: "relativePath",
flex: 2,
},
{
headerName: "Created At",
field: "createdAt",
flex: 1,
},
{
headerName: "",
filter: false,
flex: 0.5,
},
]);

return (
<div>
<BaseAGGrid
isLoading={props.isLoading}
rowData={props.rowData}
columnDefs={columnDefs}
componentsWithCallBack={[
{
reactComponent: ConfirmSelectionButton,
callbackFunction: props.handleConfirmSelection,
},
]}
errorOverlayProps={props.errorOverlayProps}
/>
</div>
);
}
48 changes: 36 additions & 12 deletions lib/components/table/SourceDataAGGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ export type SourceDataRow = z.infer<typeof SourceDataRowSchema>;
export interface SourceDataAGGridProps {
rowData: SourceDataRow[];
isLoading: boolean;
handleDownloadSourceData: (relativePath: string) => void;
isUploading: boolean;
enableUpload: boolean;
handleDownloadSourceData: (name: string, relativePath: string) => void;
handleUploadSourceData: () => void;
errorOverlayProps?: {
errorStatus: boolean;
Expand All @@ -36,31 +38,49 @@ export interface SourceDataAGGridProps {

interface DownloadSourceDataButtonParams {
context: {
handleDownloadSourceData: (relativePath: string) => void;
handleDownloadSourceData: (name: string, relativePath: string) => void;
};
data: {
name: string;
relativePath: string;
};
}

const DownloadSourceDataButton = (params: DownloadSourceDataButtonParams) => {
const handleClick = () => {
params.context.handleDownloadSourceData(params.data.relativePath);
params.context.handleDownloadSourceData(
params.data.name,
params.data.relativePath,
);
};

return (
<ShadcnButton label={"Download"} variant="default" onClick={handleClick} />
);
};

const UploadSourceDataComponent = (handleUploadSourceData: () => void) => {
return (
<ShadcnButton
label={"Upload"}
variant="default"
onClick={handleUploadSourceData}
/>
);
const UploadSourceDataComponent = (
enableUpload: boolean,
isUploading: boolean,
handleUploadSourceData: () => void,
) => {
if (!enableUpload) {
return null;
}

if (isUploading) {
return (
<ShadcnButton label={"Uploading..."} variant="default" disabled={true} />
);
} else {
return (
<ShadcnButton
label={"Upload"}
variant="default"
onClick={handleUploadSourceData}
/>
);
}
};

/**
Expand Down Expand Up @@ -114,7 +134,11 @@ export function SourceDataAGGrid(props: SourceDataAGGridProps) {
rowData={props.rowData}
columnDefs={columnDefs}
additionalComponentsLeft={[
UploadSourceDataComponent(props.handleUploadSourceData),
UploadSourceDataComponent(
props.enableUpload,
props.isUploading,
props.handleUploadSourceData,
),
]}
errorOverlayProps={props.errorOverlayProps}
// @ts-expect-error TODO: fix typing here somehow, passing "AGGridProps = { {context = ... } }" to "BaseAGGrid" doesn't work
Expand Down
Loading