chore: minor ui improvement (#3352)

This commit is contained in:
Faisal Amir 2024-08-13 09:32:59 +07:00 committed by GitHub
parent fcaf98a2fa
commit 6dd387db2b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 63 additions and 45 deletions

View File

@ -85,7 +85,11 @@ const DetailModelGroup: React.FC<Props> = ({ category, onBackClicked }) => {
<div className="w-full md:w-1/2"> <div className="w-full md:w-1/2">
<Input <Input
prefixIcon={<Search size={16} />} prefixIcon={<Search size={16} />}
placeholder="Search" placeholder={
category === 'HuggingFace'
? 'Search or paste Hugging Face URL'
: 'Search'
}
value={filter} value={filter}
onChange={onFilterChange} onChange={onFilterChange}
/> />

View File

@ -1,7 +1,5 @@
import { Fragment } from 'react' import { Fragment } from 'react'
import Image from 'next/image'
import BlankState from '@/containers/BlankState' import BlankState from '@/containers/BlankState'
import useModelHub from '@/hooks/useModelHub' import useModelHub from '@/hooks/useModelHub'
@ -24,11 +22,11 @@ const HubScreenFilter: React.FC<Props> = ({ queryText }) => {
const huggingFaceModels = data.modelCategories.get('HuggingFace') ?? [] const huggingFaceModels = data.modelCategories.get('HuggingFace') ?? []
const remoteModels: HfModelEntry[] = [] const remoteModels: HfModelEntry[] = []
Object.entries(data.modelCategories).forEach(([key, value]) => { for (const [key, value] of data.modelCategories) {
if (key !== 'HuggingFace' && key !== 'BuiltInModels') { if (key !== 'HuggingFace' && key !== 'BuiltInModels') {
remoteModels.push(...value) remoteModels.push(...value)
} }
}) }
const filteredBuiltInModels = builtInModels.filter((model) => { const filteredBuiltInModels = builtInModels.filter((model) => {
return model.name.toLowerCase().includes(queryText.toLowerCase()) return model.name.toLowerCase().includes(queryText.toLowerCase())
@ -57,19 +55,13 @@ const HubScreenFilter: React.FC<Props> = ({ queryText }) => {
<BlankState title="No search results found" /> <BlankState title="No search results found" />
</div> </div>
) : ( ) : (
<div className="mx-auto mt-6 flex h-full w-full max-w-[650px] flex-col gap-6 py-6"> <div className="mx-auto mt-6 flex h-full w-full max-w-[650px] flex-col gap-4 py-4">
{isOnDevice && ( {isOnDevice && (
<Fragment> <Fragment>
<div className="mt-4 flex items-center gap-2 first:mt-0"> <div className="mt-4 flex items-center gap-2 first:mt-0">
<Image
width={24}
height={24}
src="icons/app_icon.svg"
alt="Built-In Models"
/>
<h1 className="text-lg font-semibold">On-Device Models</h1> <h1 className="text-lg font-semibold">On-Device Models</h1>
</div> </div>
<div className="w-full"> <div className="-mt-2 w-full">
{filteredBuiltInModels.map((hfModelEntry) => ( {filteredBuiltInModels.map((hfModelEntry) => (
<BuiltInModelCard key={hfModelEntry.id} {...hfModelEntry} /> <BuiltInModelCard key={hfModelEntry.id} {...hfModelEntry} />
))} ))}

View File

@ -55,7 +55,7 @@ const HuggingFaceModelCard: React.FC<HfModelEntry> = ({
</div> </div>
<div className="pointer-events-auto flex flex-col items-end gap-2"> <div className="pointer-events-auto flex flex-col items-end gap-2">
<DownloadContainer modelHandle={name} /> <DownloadContainer modelHandle={name} />
<span className="flex items-center gap-1 text-sm font-medium leading-3"> <span className="flex items-center gap-1 text-sm font-medium leading-3 text-[hsla(var(--text-secondary))]">
{addThousandSeparator(downloads)} {addThousandSeparator(downloads)}
<CloudDownload size={14} /> <CloudDownload size={14} />
</span> </span>

View File

@ -40,27 +40,51 @@ const DataMigration: React.FC = () => {
}, [threads, deleteThread]) }, [threads, deleteThread])
return ( return (
<div className="flex w-full flex-col items-start justify-between gap-4 border-b border-[hsla(var(--app-border))] py-4 first:pt-0 last:border-none sm:flex-row"> <>
<div className="space-y-1"> <div className="flex w-full flex-col items-start justify-between gap-4 border-b border-[hsla(var(--app-border))] py-4 first:pt-0 last:border-none sm:flex-row">
<div className="flex gap-x-2"> <div className="space-y-1">
<h6 className="font-semibold capitalize"> <div className="flex gap-x-2">
Migrate data from old version of Jan app <h6 className="font-semibold capitalize">
</h6> Data Migration from Older Versions
</h6>
</div>
<p className="font-medium leading-relaxed text-[hsla(var(--text-secondary))]">
From version 0.6, Jan uses Cortex as its core engine. Without
migration, your previous threads and models may be inaccessible.
Migrate your data to maintain access in the latest version.
</p>
</div>
<div className="flex flex-shrink-0 flex-row gap-x-2">
<Button
theme="primary"
onClick={onStartMigrationClick}
variant="soft"
>
Migrate Now
</Button>
</div> </div>
<p className="font-medium leading-relaxed text-[hsla(var(--text-secondary))]">
Migrate multiple times can cause duplicate threads, please consider
using the remove threads button to clean up existing threads data
</p>
</div> </div>
<div className="flex flex-shrink-0 flex-row gap-x-2"> <div className="flex w-full flex-col items-start justify-between gap-4 border-b border-[hsla(var(--app-border))] py-4 first:pt-0 last:border-none sm:flex-row">
<Button theme="primary" onClick={onStartMigrationClick}> <div className="space-y-1">
Start migration <div className="flex gap-x-2">
</Button> <h6 className="font-semibold capitalize">Delete All Threads</h6>
<Button theme="destructive" onClick={onCleanUpDataClick}> </div>
Remove threads and messages <p className="font-medium leading-relaxed text-[hsla(var(--text-secondary))]">
</Button> Multiple migrations may create duplicate threads. Use this button to
clean up if needed.
</p>
</div>
<div className="flex flex-shrink-0 flex-row gap-x-2">
<Button
theme="destructive"
onClick={onCleanUpDataClick}
variant="soft"
>
Remove All Threads
</Button>
</div>
</div> </div>
</div> </>
) )
} }

View File

@ -52,7 +52,7 @@ export default function AppearanceOptions() {
<h6 className="font-semibold capitalize">Appearance</h6> <h6 className="font-semibold capitalize">Appearance</h6>
</div> </div>
<p className="font-medium leading-relaxed text-[hsla(var(--text-secondary))]"> <p className="font-medium leading-relaxed text-[hsla(var(--text-secondary))]">
Select a color theme Select a color theme.
</p> </p>
</div> </div>
<Select <Select
@ -68,7 +68,7 @@ export default function AppearanceOptions() {
<h6 className="font-semibold capitalize">Interface theme</h6> <h6 className="font-semibold capitalize">Interface theme</h6>
</div> </div>
<p className="font-medium leading-relaxed text-[hsla(var(--text-secondary))]"> <p className="font-medium leading-relaxed text-[hsla(var(--text-secondary))]">
Translucent option is only available for some theme Translucent option is only available for some theme.
</p> </p>
</div> </div>
<div className="flex items-center gap-x-2"> <div className="flex items-center gap-x-2">
@ -97,7 +97,7 @@ export default function AppearanceOptions() {
<h6 className="font-semibold capitalize">Spell Check</h6> <h6 className="font-semibold capitalize">Spell Check</h6>
</div> </div>
<p className=" font-medium leading-relaxed text-[hsla(var(--text-secondary))]"> <p className=" font-medium leading-relaxed text-[hsla(var(--text-secondary))]">
Toggle to disable spell checking. Toggle to enable or disable spell checking.
</p> </p>
</div> </div>
<div className="flex-shrink-0"> <div className="flex-shrink-0">

View File

@ -4,7 +4,6 @@ import {
ScrollArea, ScrollArea,
Table, Table,
TableBody, TableBody,
TableCaption,
TableCell, TableCell,
TableHead, TableHead,
TableHeader, TableHeader,
@ -46,7 +45,6 @@ const EngineSetting: React.FC = () => {
<ScrollArea className="h-full w-full"> <ScrollArea className="h-full w-full">
<div className="p-4"> <div className="p-4">
<Table> <Table>
<TableCaption className="text-xl font-bold">Engines</TableCaption>
<TableHeader> <TableHeader>
<TableRow> <TableRow>
<TableHead>Engine name</TableHead> <TableHead>Engine name</TableHead>

View File

@ -23,11 +23,11 @@ const availableHotkeys = [
}, },
{ {
combination: 'Enter', combination: 'Enter',
description: 'Send a message', description: 'Send a message (in input field)',
}, },
{ {
combination: 'Shift Enter', combination: 'Shift Enter',
description: 'Insert new line in input box', description: 'Insert a new line (in input field)',
}, },
{ {
combination: 'Arrow Up', combination: 'Arrow Up',

View File

@ -194,7 +194,7 @@ const ModelItem: React.FC<Props> = ({ model }) => {
{model.model} {model.model}
</h6> </h6>
{model.engine === 'cortex.llamacpp' && ( {model.engine === 'cortex.llamacpp' && (
<div className="flex gap-x-8"> <div className="flex justify-end gap-x-8 text-right">
<p <p
className="line-clamp-1 max-w-[120px] text-[hsla(var(--text-secondary))] xl:max-w-none" className="line-clamp-1 max-w-[120px] text-[hsla(var(--text-secondary))] xl:max-w-none"
title={model.model} title={model.model}

View File

@ -6,7 +6,7 @@ import { LlmEngines } from '@janhq/core'
import { Button, ScrollArea } from '@janhq/joi' import { Button, ScrollArea } from '@janhq/joi'
import { useAtomValue, useSetAtom } from 'jotai' import { useAtomValue, useSetAtom } from 'jotai'
import { ImportIcon, UploadCloudIcon } from 'lucide-react' import { UploadIcon, UploadCloudIcon } from 'lucide-react'
import { twMerge } from 'tailwind-merge' import { twMerge } from 'tailwind-merge'
@ -87,7 +87,7 @@ const MyModels = () => {
theme="ghost" theme="ghost"
onClick={onImportModelClick} onClick={onImportModelClick}
> >
<ImportIcon size={16} className="mr-2" /> <UploadIcon size={16} className="mr-2" />
<p>Import Model</p> <p>Import Model</p>
</Button> </Button>
</div> </div>

View File

@ -24,7 +24,7 @@ const CopyOverInstruction: React.FC = () => {
) )
return ( return (
<div className="flex w-full flex-row items-center justify-center gap-x-2"> <div className="mt-2 flex w-full flex-row items-center justify-center gap-x-2">
<h6 className="flex-1 font-medium">Save instructions for new threads</h6> <h6 className="flex-1 font-medium">Save instructions for new threads</h6>
<Switch <Switch
checked={copyOverInstructionEnabled} checked={copyOverInstructionEnabled}

View File

@ -40,7 +40,7 @@ const AssistantSettingContainer: React.FC = () => {
) )
return ( return (
<div className="flex flex-col space-y-4 p-4"> <div className="flex flex-col p-4">
<label <label
id="assistant-instructions" id="assistant-instructions"
className="mb-2 inline-block font-bold" className="mb-2 inline-block font-bold"
@ -50,7 +50,7 @@ const AssistantSettingContainer: React.FC = () => {
<TextArea <TextArea
rows={5} rows={5}
id="assistant-instructions" id="assistant-instructions"
placeholder="Eg. You are a helpful assistant." placeholder="e.g., You are a helpful assistant."
value={instructions} value={instructions}
onChange={onInstructionChanged} onChange={onInstructionChanged}
/> />