Skip to content

Commit 32154d8

Browse files
Move action button next to search bar and fix overflow of knowledge page (#28)
Fixes #20. - Fix: Now footer stays at bottom - Move floating action button next to search bar.
1 parent e75915d commit 32154d8

7 files changed

Lines changed: 111 additions & 101 deletions

File tree

src/locales/de/translation.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@
8888
"label": "Name",
8989
"noData": "Keine Dateien vorhanden",
9090
"inputPlaceholder": "Suche nach Dateien oder Tags",
91+
"uploadButton": "Neue Datei hochladen",
9192
"status": {
9293
"label": "Status",
9394
"succeeded": "Erfolgreich",

src/locales/en/translation.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@
8888
"label": "Label",
8989
"noData": "No data available",
9090
"inputPlaceholder": "Search for files or tags",
91+
"uploadButton": "Upload new file",
9192
"status": {
9293
"label": "Status",
9394
"succeeded": "Successful",

src/views/knowledge/DataTable.tsx

Lines changed: 81 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,13 @@ import { Input } from "@/components/ui/input";
2727
import type { Knowledge } from "@/api";
2828
import { t } from "i18next";
2929
import { DataTablePagination } from "./Pagination";
30+
import { Button } from "@/components/ui/button";
31+
import { Upload } from "lucide-react";
3032

3133
interface DataTableProps {
3234
columns: ColumnDef<Knowledge>[];
3335
data: Knowledge[];
36+
setUploadDialogOpen: (open: boolean) => void;
3437
}
3538

3639
const globalFilterFn: FilterFn<Knowledge> = (row, _columnId, filterValue) => {
@@ -58,7 +61,11 @@ const globalFilterFn: FilterFn<Knowledge> = (row, _columnId, filterValue) => {
5861
return visibleMatch || tagMatch || permissionMatch;
5962
};
6063

61-
export default function DataTable({ columns, data }: Readonly<DataTableProps>) {
64+
export default function DataTable({
65+
columns,
66+
data,
67+
setUploadDialogOpen,
68+
}: Readonly<DataTableProps>) {
6269
const [sorting, setSorting] = useState<SortingState>([
6370
{ id: "label", desc: false },
6471
]);
@@ -86,79 +93,84 @@ export default function DataTable({ columns, data }: Readonly<DataTableProps>) {
8693
});
8794

8895
return (
89-
<>
90-
<div>
91-
{/*Search Bar*/}
92-
<div className="flex items-center py-4">
93-
<Input
94-
placeholder={t("knowledgePage.table.inputPlaceholder")}
95-
value={globalFilter}
96-
onChange={(event) => {
97-
setGlobalFilter(event.target.value);
98-
}}
99-
className="max-w-sm"
100-
/>
101-
</div>
96+
<div>
97+
{/*Search Bar*/}
98+
<div className="flex items-center justify-between py-4">
99+
<Input
100+
placeholder={t("knowledgePage.table.inputPlaceholder")}
101+
value={globalFilter}
102+
onChange={(event) => {
103+
setGlobalFilter(event.target.value);
104+
}}
105+
className="max-w-sm"
106+
/>
107+
<Button
108+
onClick={() => {
109+
setUploadDialogOpen(true);
110+
}}
111+
>
112+
<Upload />
113+
{t("knowledgePage.table.uploadButton")}
114+
</Button>
115+
</div>
102116

103-
<div className="rounded-md border">
104-
<Table>
105-
<TableHeader>
106-
{table.getHeaderGroups().map((headerGroup) => (
107-
<TableRow key={headerGroup.id}>
108-
{headerGroup.headers.map((header) => (
109-
<TableHead key={header.id}>
110-
{header.isPlaceholder
111-
? null
112-
: flexRender(
113-
header.column.columnDef.header,
114-
header.getContext(),
115-
)}
116-
</TableHead>
117-
))}
118-
</TableRow>
119-
))}
120-
</TableHeader>
121-
<TableBody>
122-
{table.getRowModel().rows.length ? (
123-
table.getRowModel().rows.map((row) => (
124-
<React.Fragment key={row.id}>
125-
<TableRow>
126-
{row.getVisibleCells().map((cell) => (
127-
<TableCell key={cell.id}>
128-
{flexRender(
129-
cell.column.columnDef.cell,
130-
cell.getContext(),
131-
)}
132-
</TableCell>
133-
))}
117+
<div className="rounded-md border">
118+
<Table>
119+
<TableHeader>
120+
{table.getHeaderGroups().map((headerGroup) => (
121+
<TableRow key={headerGroup.id}>
122+
{headerGroup.headers.map((header) => (
123+
<TableHead key={header.id}>
124+
{header.isPlaceholder
125+
? null
126+
: flexRender(
127+
header.column.columnDef.header,
128+
header.getContext(),
129+
)}
130+
</TableHead>
131+
))}
132+
</TableRow>
133+
))}
134+
</TableHeader>
135+
<TableBody>
136+
{table.getRowModel().rows.length ? (
137+
table.getRowModel().rows.map((row) => (
138+
<React.Fragment key={row.id}>
139+
<TableRow>
140+
{row.getVisibleCells().map((cell) => (
141+
<TableCell key={cell.id}>
142+
{flexRender(
143+
cell.column.columnDef.cell,
144+
cell.getContext(),
145+
)}
146+
</TableCell>
147+
))}
148+
</TableRow>
149+
{row.getIsExpanded() && (
150+
<TableRow className="bg-secondary hover:bg-secondary">
151+
<TableCell colSpan={columns.length}>
152+
<TableAccordion knowledge={row.original} />
153+
</TableCell>
134154
</TableRow>
135-
{row.getIsExpanded() && (
136-
<TableRow className="bg-secondary hover:bg-secondary">
137-
<TableCell colSpan={columns.length}>
138-
<TableAccordion knowledge={row.original} />
139-
</TableCell>
140-
</TableRow>
141-
)}
142-
</React.Fragment>
143-
))
144-
) : (
145-
<TableRow>
146-
<TableCell
147-
colSpan={columns.length}
148-
className="h-24 text-center"
149-
>
150-
{t("knowledgePage.table.noData")}
151-
</TableCell>
152-
</TableRow>
153-
)}
154-
</TableBody>
155-
</Table>
156-
</div>
155+
)}
156+
</React.Fragment>
157+
))
158+
) : (
159+
<TableRow>
160+
<TableCell
161+
colSpan={columns.length}
162+
className="h-24 text-center"
163+
>
164+
{t("knowledgePage.table.noData")}
165+
</TableCell>
166+
</TableRow>
167+
)}
168+
</TableBody>
169+
</Table>
157170
</div>
158-
159171
<div className="pt-2">
160172
<DataTablePagination<Knowledge> table={table} />
161173
</div>
162-
</>
174+
</div>
163175
);
164176
}

src/views/knowledge/Knowledge.tsx

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
import DataTable from "./DataTable";
22
import { useState } from "react";
3-
import { FloatingActionButton } from "@/components/ui/floating-action-button";
4-
import { Dialog, DialogTrigger } from "@/components/ui/dialog";
53
import UploadFileDialog from "./dialog/UploadFileDialog";
64
import { useGetKnowledgeList } from "@/services/GetKnowledgeListService";
75
import Columns from "./Columns";
@@ -18,7 +16,7 @@ import PermissionDialog from "./dialog/PermissionDialog";
1816
export default function Knowledge() {
1917
const { allKnowledge } = useGetKnowledgeList();
2018
const { toast } = useToast();
21-
const [isDialogOpen, setIsDialogOpen] = useState(false);
19+
const [uploadDialogOpen, setUploadDialogOpen] = useState(false);
2220
const [showPdfWithUuid, setShowPdfWithUuid] = useState<string | null>(null);
2321
const [pdfLoading, setPdfLoading] = useState<string | null>(null);
2422
const { downloadFile } = useDownloadFile();
@@ -46,33 +44,26 @@ export default function Knowledge() {
4644
};
4745

4846
return (
49-
<div className={`flex h-full mt-0 relative`}>
50-
<div className="container mx-auto py-10">
47+
<div className="flex relative px-2 pb-8">
48+
<div className="container">
5149
<DataTable
5250
columns={Columns(
5351
onClickFile,
5452
setOpenTagEditDialogKnowledgeId,
5553
setOpenPermissionDialogKnowledgeId,
5654
)}
5755
data={allKnowledge}
56+
setUploadDialogOpen={setUploadDialogOpen}
5857
/>
5958
</div>
60-
<Dialog open={isDialogOpen} onOpenChange={setIsDialogOpen}>
61-
<DialogTrigger asChild>
62-
<FloatingActionButton
63-
onClick={() => {
64-
setIsDialogOpen(true);
65-
}}
66-
/>
67-
</DialogTrigger>
68-
<UploadFileDialog
69-
knowledge={null}
70-
onClose={() => {
71-
setIsDialogOpen(false);
72-
}}
73-
resetSelectedFiles={!isDialogOpen}
74-
/>
75-
</Dialog>
59+
60+
<UploadFileDialog
61+
knowledge={null}
62+
onClose={() => {
63+
setUploadDialogOpen(false);
64+
}}
65+
open={uploadDialogOpen}
66+
/>
7667

7768
<TagEditDialog
7869
knowledgeId={openTagEditDialogKnowledgeId}

src/views/knowledge/KnowledgeOptions.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ export default function KnowledgeOptions({
130130
onClose={() => {
131131
setIsDialogOpen(false);
132132
}}
133-
resetSelectedFiles={!isDialogOpen}
133+
open={isDialogOpen}
134134
/>
135135
</Dialog>
136136
<DropdownMenuItem

src/views/knowledge/dialog/UploadFileDialog.tsx

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import { Knowledge } from "@/api";
22
import { Button } from "@/components/ui/button";
33
import {
4-
DialogPortal,
54
DialogOverlay,
65
DialogContent,
76
DialogDescription,
87
DialogTitle,
98
DialogFooter,
9+
Dialog,
1010
} from "@/components/ui/dialog";
1111
import { Spinner } from "@/components/ui/spinner";
1212
import useAddFileSourceApi from "@/hooks/api/useAddFileSourceApi";
@@ -22,7 +22,7 @@ import { useToast } from "@/hooks/use-toast";
2222
interface UploadFileDialogProps {
2323
knowledge?: Readonly<Knowledge> | null;
2424
onClose: () => void;
25-
resetSelectedFiles: boolean;
25+
open: boolean;
2626
}
2727

2828
type UploadStatus = "idle" | "uploading" | "success" | "error";
@@ -31,7 +31,7 @@ type UploadStatus = "idle" | "uploading" | "success" | "error";
3131
export default function UploadFileDialog({
3232
knowledge,
3333
onClose,
34-
resetSelectedFiles,
34+
open,
3535
}: Readonly<UploadFileDialogProps>) {
3636
const onDrop = useCallback((acceptedFiles: SetStateAction<File[] | null>) => {
3737
setFiles(acceptedFiles);
@@ -51,10 +51,10 @@ export default function UploadFileDialog({
5151
const [status, setStatus] = useState<UploadStatus>("idle");
5252

5353
useEffect(() => {
54-
if (resetSelectedFiles) {
54+
if (!open) {
5555
setFiles(null);
5656
}
57-
}, [resetSelectedFiles]);
57+
}, [open]);
5858

5959
useEffect(() => {
6060
if (status === "success") {
@@ -136,7 +136,12 @@ export default function UploadFileDialog({
136136
};
137137

138138
return (
139-
<DialogPortal>
139+
<Dialog
140+
open={open}
141+
onOpenChange={(open) => {
142+
if (!open) onClose();
143+
}}
144+
>
140145
<DialogOverlay className="fixed inset-0 z-50 bg-black bg-opacity-30 backdrop-blur-sm" />
141146
<DialogContent className="fixed left-1/2 top-1/2 z-50 grid w-full max-w-lg transform -translate-x-1/2 -translate-y-1/2 gap-4 border p-6 shadow-lg duration-200 sm:rounded-lg">
142147
<DialogTitle>
@@ -181,6 +186,6 @@ export default function UploadFileDialog({
181186
)}
182187
</DialogFooter>
183188
</DialogContent>
184-
</DialogPortal>
189+
</Dialog>
185190
);
186191
}

src/views/overlays/Overlay.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,22 +22,22 @@ export function Overlay({ children }: Readonly<OverlayProps>) {
2222

2323
return (
2424
<Sidebar>
25-
<div ref={headerRef} className="sticky top-0 z-40 ">
25+
<div ref={headerRef} className="top-0 z-40 ">
2626
<Header
2727
onClickNewSession={() => {
2828
onClickNewSession();
2929
}}
3030
/>
3131
</div>
3232
<div
33-
className="mx-4"
33+
className="mx-4 overflow-y-auto"
3434
style={{
3535
height: `calc(100dvh - ${headerSize.height.toString()}px - ${footerSize.height.toString()}px)`,
3636
}}
3737
>
3838
{children}
3939
</div>
40-
<div ref={footerRef} className="sticky bottom-0 z-40">
40+
<div ref={footerRef} className="bottom-0 z-40">
4141
<Footer />
4242
</div>
4343
</Sidebar>

0 commit comments

Comments
 (0)