Skip to content

Commit

Permalink
ui: redesign phase 1
Browse files Browse the repository at this point in the history
  • Loading branch information
jazelly committed Jul 3, 2024
1 parent 601782f commit 67dc1b2
Show file tree
Hide file tree
Showing 31 changed files with 180 additions and 808 deletions.
24 changes: 4 additions & 20 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,13 @@ import UploadDatasets, {
} from '@/components/Modals/UploadDatasets';
import { TrainerMessageMapProvider } from './contexts/TrainerMessageMap.context';
import Settings from './pages/Settings.page';
import NotFound from './pages/404.page';

const Logs = lazy(() => import('@/pages/Logs.page'));
const InvitePage = lazy(() => import('@/pages/Invite'));
const Pipeline = lazy(() => import('@/pages/Pipeline.page'));
// const WorkspaceChat = lazy(() => import("@/pages/WorkspaceChat")); // TODO: integarte to testing field
const Dashboard = lazy(() => import('@/pages/Dashboard.page'));
const AdminUsers = lazy(() => import('@/pages/Admin/Users'));
const AdminInvites = lazy(() => import('@/pages/Admin/Invitations'));
const AdminWorkspaces = lazy(() => import('@/pages/Admin/Workspaces'));
const AdminSystem = lazy(() => import('@/pages/Admin/System'));
const GeneralChats = lazy(() => import('@/pages/GeneralSettings/Chats'));
const GeneralAppearance = lazy(
() => import('@/pages/GeneralSettings/Appearance')
);
const GeneralApiKeys = lazy(() => import('@/pages/GeneralSettings/ApiKeys'));
const GeneralLLMPreference = lazy(
() => import('@/pages/GeneralSettings/LLMPreference')
);
const PrivacyAndData = lazy(
() => import('@/pages/GeneralSettings/PrivacyAndData')
);

export default function App() {
const sidebarRef = useRef(null);
Expand All @@ -53,14 +39,14 @@ export default function App() {
<LogoProvider>
<PermalinksProvider>
<TrainerMessageMapProvider>
<div className="bg-main-base flex h-full">
<div className="bg-main-base text-white flex h-full">
{showingUpload && (
<UploadDatasets hideModal={hideUploadModal} />
)}

{!isMobile && (
<div
className={`w-16 h-full flex-shrink-0 p-2 flex flex-col items-center justify-between`}
className={`w-16 h-full bg-main-dark flex-shrink-0 p-2 flex flex-col items-center justify-between`}
ref={sidebarRef}
>
<Sidebar />
Expand Down Expand Up @@ -90,13 +76,11 @@ export default function App() {
element={<InvitePage />}
/>

{/* Admin */}
<Route
path="/settings/*"
element={<AdminRoute Component={Settings} />}
/>

{/* Manager */}
<Route path="*" element={<NotFound />} />
</Routes>
</div>
<ToastContainer />
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/components/Dropdown.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,13 @@ const Dropdown = ({
<div className="flex flex-col items-start">
{!!label && (
<div
className={`mr-2 font-semibold text-main-title flex items-center justify-center h-full`}
className={`mr-2 font-semibold flex items-center justify-center h-full`}
>
{label}
</div>
)}
<div
className={`relative h-10 mt-1 w-full ${!disabled && 'cursor-pointer'}`}
className={`relative h-10 mt-1 w-full ${!disabled && 'cursor-pointer'} text-main-menu font-semibold`}
onClick={toggleDropdown}
ref={dropdownRef}
>
Expand All @@ -96,7 +96,7 @@ const Dropdown = ({
animate={{ opacity: 1, maxHeight: 200 }}
exit={{ opacity: 0, maxHeight: 0 }}
transition={{ duration: 0.3 }}
className="absolute z-50 left-0 w-full bg-white border rounded shadow overflow-hidden"
className="absolute z-50 left-0 w-full bg-white text-main-menu font-semibold border rounded shadow overflow-hidden"
style={{ top: '100%' }}
>
{options.length === 0 ? (
Expand Down
37 changes: 6 additions & 31 deletions frontend/src/components/FinetunePanel.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@ import { AllJobOptions, IDataset } from '@/types/dashboard.type';
import { CaretCircleDoubleRight } from '@phosphor-icons/react';
import Job from '@/models/job.model';
import { useNavigate } from 'react-router-dom';
import type { TrainerPayload, TrainerResponseWS } from '@/types/dashboard.type';
import JSONView from 'react-json-view';
import { TrainerMessageMapContext } from '@/contexts/TrainerMessageMap.context';
import Scrollable from './reusable/Scrollable.component'; // Import the ScrollBar component
import Tip from './reusable/Tip.component';

export interface FinetunePanelProps {
jobOptions: AllJobOptions | undefined;
Expand Down Expand Up @@ -96,11 +95,9 @@ const FinetunePanel = ({ jobOptions, setJobOptions }: FinetunePanelProps) => {
return (
<Scrollable>
{/* Wrap the content with ScrollBar */}
<div className="flex flex-col items-startstart bg-main-white-gradient px-4 py-3 h-full w-full">
<div className="flex flex-col px-4 py-3 h-full w-full">
<div className="flex justify-between">
<div className="text-lg font-semibold text-main-title">
Submit a finetuning job
</div>
<div className="text-lg font-semibold">Submit a finetuning job</div>
<div
onMouseEnter={() => {
setSubmitHovered(true);
Expand All @@ -113,17 +110,11 @@ const FinetunePanel = ({ jobOptions, setJobOptions }: FinetunePanelProps) => {
onClick={handleSubmitJob}
style={{ backgroundColor: '#0aa8ff' }}
>
<span className={`text-white`}>Submit</span>
<CaretCircleDoubleRight
weight={submitHovered ? 'fill' : 'bold'}
size={24}
color="#ffffff"
/>
<span className={`text-white font-semibold`}>Submit</span>
<CaretCircleDoubleRight size={24} color="#ffffff" />
</div>
</div>
{submitJobError !== '' && (
<div className="text-red-500 text-sm italic">{submitJobError}</div>
)}
{submitJobError !== '' && <Tip type="error" message={submitJobError} />}
<Dropdown
placeholder="Base model"
options={jobOptions?.baseModels ?? []}
Expand Down Expand Up @@ -151,22 +142,6 @@ const FinetunePanel = ({ jobOptions, setJobOptions }: FinetunePanelProps) => {
label="Dataset"
disabled={!jobOptions}
/>

{jobOptions && (
<div
className={`flex flex-col items-startstart px-2 py-2 gap-y-4 h-full ${'bg-red'}`}
>
<div className="text-lg font-semibold text-main-title">
Training Hyperparameters
</div>
<JSONView
onEdit={handleHyperparametersStringChange}
src={jobOptions?.hyperparameters}
name="hyperparameters"
enableClipboard={true}
/>
</div>
)}
</div>
</Scrollable>
);
Expand Down
55 changes: 0 additions & 55 deletions frontend/src/components/Footer.tsx

This file was deleted.

16 changes: 0 additions & 16 deletions frontend/src/components/SettingsSidebar.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -265,22 +265,6 @@ const SidebarOptions = ({ user = null }: any) => (
flex={true}
allowedRole={['admin']}
/>
<Option
href={paths.settings.audioPreference()}
btnText="Voice and Speech Support"
icon={<Microphone className="h-5 w-5 flex-shrink-0" />}
user={user}
flex={true}
allowedRole={['admin']}
/>
<Option
href={paths.settings.transcriptionPreference()}
btnText="Transcription Model"
icon={<ClosedCaptioning className="h-5 w-5 flex-shrink-0" />}
user={user}
flex={true}
allowedRole={['admin']}
/>
<Option
href={paths.settings.security()}
btnText="Security"
Expand Down
17 changes: 6 additions & 11 deletions frontend/src/components/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,12 @@ export default function Sidebar() {
<>
<Link
to={paths.home()}
className="flex shrink-0 max-w-[100%] items-center justify-start mx-[4px] my-[16px]"
className="flex shrink-0 max-w-[100%] items-center justify-start mt-1"
aria-label="Home"
>
<img
src={logo}
alt="Logo"
className="rounded h-[36px]"
style={{ objectFit: 'contain' }}
/>
<img src={logo} alt="Logo" style={{ objectFit: 'contain' }} />
</Link>
<div className="flex flex-col h-full overflow-x-hidden">
<div className="flex flex-col h-full overflow-x-hidden mt-3">
<div className="flex-grow flex flex-col min-w-[24px] overflow-y-scroll no-scroll pb-8 gap-y-2">
<div className="flex gap-x-2 items-center justify-between">
<button
Expand All @@ -56,7 +51,7 @@ export default function Sidebar() {
className="flex flex-grow h-[44px] gap-x-2 py-[5px] px-2.5 mb-2 rounded-[8px] text-sidebar justify-center items-center hover:bg-opacity-80 transition-all duration-300"
>
<Circuitry
color={isNewingJob || isViewingJob ? '#5f27cd' : '#748497'}
color={isNewingJob || isViewingJob ? '#FFF' : '#7C8690'}
size={28}
weight="fill"
/>
Expand All @@ -71,7 +66,7 @@ export default function Sidebar() {
>
<AlignLeft
size={28}
color={isViewingLog ? '#5f27cd' : '#748497'}
color={isViewingLog ? '#FFF' : '#7C8690'}
weight="fill"
/>
</button>
Expand All @@ -85,7 +80,7 @@ export default function Sidebar() {
>
<Wrench
size={28}
color={isViewingSettings ? '#5f27cd' : '#748497'}
color={isViewingSettings ? '#FFF' : '#7C8690'}
weight="fill"
/>
</button>
Expand Down
3 changes: 0 additions & 3 deletions frontend/src/components/SidebarMobileHeader.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,6 @@ export default function SidebarMobileHeader() {
</div>
</div>
</div>
<div>
<Footer />
</div>
</div>
</div>
</div>
Expand Down
35 changes: 35 additions & 0 deletions frontend/src/components/reusable/Tag.component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { Question, Warning, WarningCircle } from '@phosphor-icons/react';
import React, { useState, useMemo } from 'react';

interface TagProps {
name: string;
backgroundColor: string;
}

const Tag = ({ backgroundColor, name }) => {
const textColor = useMemo(() => {
const color =
backgroundColor.charAt(0) === '#'
? backgroundColor.substring(1, 7)
: backgroundColor;
const r = parseInt(color.substring(0, 2), 16); // hexToR
const g = parseInt(color.substring(2, 4), 16); // hexToG
const b = parseInt(color.substring(4, 6), 16); // hexToB
return r * 0.299 + g * 0.587 + b * 0.114 > 186 ? '#000000' : '#FFFFFF';
}, [backgroundColor]);

return (
<span
style={{
backgroundColor,
color: textColor,
padding: '4px 8px',
borderRadius: '4px',
}}
>
{name}
</span>
);
};

export default Tag;
20 changes: 20 additions & 0 deletions frontend/src/components/reusable/Tip.component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Question, Warning, WarningCircle } from '@phosphor-icons/react';
import React from 'react';

interface TipProps {
message: string;
type: 'error' | 'info' | 'question';
}

const infoIcon = <WarningCircle size={32} color="#d7c692" weight="bold" />;
const questionIcon = <Question size={32} color="#d7c692" weight="bold" />;
const errorIcon = <Warning size={32} color="#d7c692" weight="bold" />;

export default function Tip({ message, type }: TipProps) {
return (
<div className="flex justify-center items-center">
{type === 'info' ? infoIcon : type === 'error' ? errorIcon : questionIcon}
<div className="text-main-orange text-sm font-bold italic">{message}</div>
</div>
);
}
Binary file added frontend/src/media/design/1.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added frontend/src/media/design/2.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed frontend/src/media/logo/FinetuneLLMs_transparent.png
Binary file not shown.
Binary file removed frontend/src/media/logo/design-dashboard.png
Binary file not shown.
Binary file removed frontend/src/media/logo/design-job.png
Binary file not shown.
Binary file removed frontend/src/media/logo/design-x.png
Binary file not shown.
Binary file modified frontend/src/media/logo/fllms-transparent.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 0 additions & 25 deletions frontend/src/models/admin.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,31 +155,6 @@ const Admin = {
});
},

// System Preferences
systemPreferences: async () => {
return await fetch(`${API_BASE}/admin/system-preferences`, {
method: 'GET',
headers: baseHeaders(),
})
.then((res) => res.json())
.catch((e) => {
console.error(e);
return null;
});
},
updateSystemPreferences: async (updates = {}) => {
return await fetch(`${API_BASE}/admin/system-preferences`, {
method: 'POST',
headers: baseHeaders(),
body: JSON.stringify(updates),
})
.then((res) => res.json())
.catch((e) => {
console.error(e);
return { success: false, error: e.message };
});
},

// API Keys
getApiKeys: async function () {
return fetch(`${API_BASE}/admin/api-keys`, {
Expand Down
Loading

0 comments on commit 67dc1b2

Please sign in to comment.