Skip to content
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
801 changes: 156 additions & 645 deletions webui/package-lock.json

Large diffs are not rendered by default.

7 changes: 2 additions & 5 deletions webui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,12 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@carbon/icons-react": "^11.44.1",
"@carbon/react": "^1.60.3",
"@carbon/styles": "^1.60.1",
"@carbon/react": "^1.65.0",
"@carbon/styles": "^1.64.0",
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"axios": "^1.7.2",
"carbon-components": "^10.58.12",
"carbon-components-react": "^8.60.3",
"oidc-client": "^1.11.5",
"react": "^18.3.1",
"react-dom": "^18.3.1",
Expand Down
8 changes: 4 additions & 4 deletions webui/src/App.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.App {
/* .App {
display: flex;
flex-direction: column;
height: 100vh;
Expand All @@ -15,12 +15,12 @@
padding: 2rem;
overflow-y: auto;
background-color: #f4f4f4;
}
} */

/* Carbon Components default styling overrides */
.bx--side-nav__items {
/* .bx--side-nav__items {
padding-top: 3rem;
}
} */

.bx--header {
background-color: #161616;
Expand Down
51 changes: 32 additions & 19 deletions webui/src/App.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import React, { Suspense } from 'react';
import { BrowserRouter as Router, Route, Routes, Navigate } from 'react-router-dom';
import { Theme, Content } from '@carbon/react';
import UIHeader from './components/Header';
import UISideNav from './components/SideNav';
import SignIn from './components/SignIn';
import Dashboard from './components/Dashboard';
import CollectionForm from './components/CollectionForm';
import { AuthProvider, useAuth } from './contexts/AuthContext';
import './css/common.css';
import React, { Suspense } from "react";
import {
BrowserRouter as Router,
Route,
Routes,
Navigate,
} from "react-router-dom";
import { Content, GlobalTheme, Theme } from "@carbon/react";
import UIHeader from "./components/Header";
import SignIn from "./components/SignIn";
import Dashboard from "./components/Dashboard";
import CollectionForm from "./components/CollectionForm";
import { AuthProvider, useAuth } from "./contexts/AuthContext";
import "./css/common.css";

function AppContent() {
const { user, loading } = useAuth();
Expand All @@ -17,32 +21,41 @@ function AppContent() {
}

return (
<Theme theme="g100">
<GlobalTheme theme="white">
<Router>
<Suspense fallback={<div>Loading...</div>}>
<div className="App">
{user && <UIHeader />}
<div className="content-wrapper">
{user && <UISideNav />}
<Content className={`main-content ${user ? 'content-shifted' : ''}`}>
<div className="content-wrapper ">
<Content
className={"main-content"}
>
<Routes>
<Route path="/signin" element={user ? <Navigate to="/dashboard" /> : <SignIn />} />
<Route
path="/signin"
element={user ? <Navigate to="/dashboard" /> : <SignIn />}
/>
<Route
path="/dashboard"
element={user ? <Dashboard /> : <Navigate to="/signin" />}
/>
<Route
path="/create-collection"
element={user ? <CollectionForm /> : <Navigate to="/signin" />}
element={
user ? <CollectionForm /> : <Navigate to="/signin" />
}
/>
<Route
path="/"
element={<Navigate to={user ? "/dashboard" : "/signin"} />}
/>
<Route path="/" element={<Navigate to={user ? "/dashboard" : "/signin"} />} />
</Routes>
</Content>
</div>
</div>
</Suspense>
</Router>
</Theme>
</GlobalTheme>
);
}

Expand All @@ -54,4 +67,4 @@ function App() {
);
}

export default App;
export default App;
76 changes: 36 additions & 40 deletions webui/src/components/CollectionForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,17 @@ import {
Tag,
ProgressBar,
ToastNotification,
ExpandableTile,
TileAboveTheFoldContent,
TileBelowTheFoldContent,
Tile,
Loading,
InlineLoading
InlineLoading,
Grid,
Column
} from '@carbon/react';
import { TrashCan } from '@carbon/icons-react';
import { TrashCan, Document } from '@carbon/icons-react';
import { createCollectionWithDocuments, getUserCollections } from '../api/api';
import { useAuth } from '../contexts/AuthContext';

const CollectionForm = ({ onSubmit }) => {
const CollectionForm = () => {
const { user, loading: authLoading } = useAuth();
const [collectionName, setCollectionName] = useState('');
const [isPrivate, setIsPrivate] = useState(false);
Expand All @@ -33,16 +33,15 @@ const CollectionForm = ({ onSubmit }) => {
const [isLoadingCollections, setIsLoadingCollections] = useState(false);

useEffect(() => {
if (user && user.id) {
fetchUserCollections(user.id);
if (user && user.uuid) {
fetchUserCollections();
}
}, [user]);

const fetchUserCollections = async (userId) => {
const fetchUserCollections = async () => {
setIsLoadingCollections(true);
try {
const collections = await getUserCollections(userId);
console.log('User collections:', collections);
const collections = await getUserCollections();
setUserCollections(Array.isArray(collections) ? collections : []);
} catch (error) {
console.error('Error fetching user collections:', error);
Expand Down Expand Up @@ -86,6 +85,7 @@ const CollectionForm = ({ onSubmit }) => {
e.preventDefault();

if (!user) {
console.error("User not authenticated");
setErrorMessage('User not authenticated. Please sign in.');
setShowError(true);
return;
Expand All @@ -101,7 +101,7 @@ const CollectionForm = ({ onSubmit }) => {
const formData = new FormData();
formData.append('collection_name', collectionName);
formData.append('is_private', isPrivate);
formData.append('user_id', user.id);
formData.append('user_id', user.uuid);

files.forEach((file) => {
formData.append('files', file);
Expand All @@ -114,8 +114,7 @@ const CollectionForm = ({ onSubmit }) => {
});
console.log('API Response:', response);
setShowSuccessToast(true);
onSubmit(response);
await fetchUserCollections(user.id);
await fetchUserCollections();
// Reset form
setCollectionName('');
setIsPrivate(false);
Expand Down Expand Up @@ -149,20 +148,20 @@ const CollectionForm = ({ onSubmit }) => {
<h2>Your Collections</h2>
{isLoadingCollections ? (
<Loading description="Loading collections" withOverlay={false} />
) : Array.isArray(userCollections) && userCollections.length > 0 ? (
userCollections.map((collection) => (
<ExpandableTile key={collection.id}>
<TileAboveTheFoldContent>
<h3>{collection.name}</h3>
<p>{Array.isArray(collection.files) && collection.files.slice(0, 3).map(file => file.filename).join(', ')}</p>
</TileAboveTheFoldContent>
<TileBelowTheFoldContent>
{Array.isArray(collection.files) && collection.files.slice(3, 10).map(file => (
<p key={file.id}>{file.filename}</p>
))}
</TileBelowTheFoldContent>
</ExpandableTile>
))
) : userCollections.length > 0 ? (
<Grid narrow className="collections-grid">
{userCollections.map((collection) => (
<Column sm={4} md={4} lg={4} key={collection.id}>
<Tile className="collection-tile">
<h3>{collection.name}</h3>
<p>
<Document size={16} /> Files: {Array.isArray(collection.files) ? collection.files.length : 'N/A'}
</p>
<p>Created: {new Date(collection.created_at).toLocaleDateString()}</p>
</Tile>
</Column>
))}
</Grid>
) : (
<p>No collections found. Create your first collection below!</p>
)}
Expand All @@ -177,24 +176,23 @@ const CollectionForm = ({ onSubmit }) => {
disabled={isUploading}
/>
<Checkbox
className="cds--label-description"
checked={isPrivate}
labelText="Private Collection?"
id="checkbox-label-1"
labelText="Private Collection"
id="private-collection-checkbox"
onChange={(e) => setIsPrivate(e.target.checked)}
disabled={isUploading}
/>
<FormItem>
<p className="cds--file--label">Upload files</p>
<p className="cds--label-description">Max file size is 5MB.</p>
<p className="cds--label-description">Max file size is 5MB. Supported formats: PDF, PPT, TXT, DOC, DOCX, XLS, XLSX</p>
<FileUploaderDropContainer
accept={[
'text/plain',
'application/pdf',
'application/msword',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'application/vnd.ms-powerpoint',
'application/vnd.openxmlformats-officedocument.presentationml.presentation',
'text/plain',
'application/msword',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'application/vnd.ms-excel',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
]}
Expand All @@ -207,17 +205,15 @@ const CollectionForm = ({ onSubmit }) => {
<div className="selected-files">
<p>Selected Files:</p>
{files.map((file, index) => (
<div key={index} style={{ display: 'flex', alignItems: 'center', marginBottom: '8px' }}>
<Tag type="gray">{file.name}</Tag>
<div key={index} className="file-tag">
<Tag type="blue">{file.name}</Tag>
<Button
kind="ghost"
size="sm"
hasIconOnly
renderIcon={TrashCan}
iconDescription="Remove file"
tooltipPosition="right"
onClick={() => handleFileRemove(index)}
style={{ marginLeft: '8px' }}
disabled={isUploading}
/>
</div>
Expand All @@ -233,7 +229,7 @@ const CollectionForm = ({ onSubmit }) => {
/>
)}

<Button type="submit" kind="primary" disabled={isUploading || files.length === 0}>
<Button type="submit" kind="primary" disabled={isUploading || files.length === 0 || !collectionName}>
{isUploading ? <InlineLoading description="Creating collection..." /> : "Create Collection"}
</Button>
</Form>
Expand Down
13 changes: 7 additions & 6 deletions webui/src/components/Dashboard.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react';
import { useAuth } from '../contexts/AuthContext';
import React from "react";
import { useAuth } from "../contexts/AuthContext";
import { Content, Theme } from "@carbon/react";

const Dashboard = () => {
const { user, loading } = useAuth();
Expand All @@ -9,11 +10,11 @@ const Dashboard = () => {
}

return (
<div>
<h1>Welcome, {user ? user.name : 'Guest'}!</h1>
<Content>
<h1>Welcome, {user ? user.name : "Guest"}!</h1>
{/* Add more dashboard content here */}
</div>
</Content>
);
};

export default Dashboard;
export default Dashboard;
39 changes: 28 additions & 11 deletions webui/src/components/Header.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,30 @@
import React, { useState } from 'react';
import React, { useState } from "react";
import {
Header as CarbonHeader,
HeaderName,
HeaderGlobalBar,
HeaderGlobalAction,
HeaderPanel,
Theme
} from '@carbon/react';
import { Menu, UserAvatar } from '@carbon/icons-react';
import { useAuth } from '../contexts/AuthContext';
Theme,
} from "@carbon/react";
import { Menu, UserAvatar } from "@carbon/icons-react";
import { useAuth } from "../contexts/AuthContext";

const Header = ({ onMenuClick }) => {
import UISideNav from "./SideNav";

const Header = () => {
const { user, logout } = useAuth();

const [isUserMenuOpen, setIsUserMenuOpen] = useState(false);
const [isMainMenuOpen, setIsMainMenuOpen] = useState(false);

const handleMainMenuOpen = () => {
// console.log(isMainMenuOpen);
setIsMainMenuOpen((prevState) => !prevState);
};

const handleUserMenuClick = () => {
setIsUserMenuOpen(prevState => !prevState);
setIsUserMenuOpen((prevState) => !prevState);
};

const handleLogout = () => {
Expand All @@ -26,7 +35,7 @@ const Header = ({ onMenuClick }) => {
return (
<Theme theme="g100">
<CarbonHeader aria-label="RAG Modulo">
<HeaderGlobalAction aria-label="Menu" onClick={onMenuClick}>
<HeaderGlobalAction aria-label="" onClick={handleMainMenuOpen}>
<Menu size={20} />
</HeaderGlobalAction>
<HeaderName href="#" prefix="">
Expand All @@ -42,11 +51,15 @@ const Header = ({ onMenuClick }) => {
</HeaderGlobalAction>
</HeaderGlobalBar>
{isUserMenuOpen && (
<HeaderPanel expanded aria-label="User Menu" className="user-menu-panel">
<HeaderPanel
expanded
aria-label="User Menu"
className="user-menu-panel"
>
<div className="user-menu">
{user ? (
<>
<p>{user.name || 'User'}</p>
<p>{user.name || "User"}</p>
<button onClick={handleLogout}>Logout</button>
</>
) : (
Expand All @@ -55,9 +68,13 @@ const Header = ({ onMenuClick }) => {
</div>
</HeaderPanel>
)}
<UISideNav
isSideNavExpanded={isMainMenuOpen}
handleSideNavExpand={handleMainMenuOpen}
/>
</CarbonHeader>
</Theme>
);
};

export default Header;
export default Header;
Loading
Loading