feat: make llm picker responsive
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/promote/production Build is passing

This commit is contained in:
RaviAnand Mohabir 2025-04-07 18:47:35 +02:00
parent 420406f9a4
commit 849e41bc06
3 changed files with 101 additions and 68 deletions

View File

@ -1,20 +1,26 @@
import { import {
ActionIcon,
Drawer,
Group, Group,
Indicator, Indicator,
Progress, Progress,
Select, Select,
Stack, Stack,
StackProps,
Tooltip, Tooltip,
} from "@mantine/core"; } from "@mantine/core";
import { IconRobotFace } from "@tabler/icons-react"; import { IconRobotFace } from "@tabler/icons-react";
import { useDisclosure } from "@mantine/hooks";
import { useMLEngine } from "./MLEngineContext"; import { useMLEngine } from "./MLEngineContext";
function LLMPicker() { function LLMPicker(props: StackProps) {
const [opened, { open, close }] = useDisclosure(false);
const { loadingModel, activeModel, selectModel, modelList } = useMLEngine(); const { loadingModel, activeModel, selectModel, modelList } = useMLEngine();
return ( return (
<Stack> <Stack {...props}>
<Group> <Group>
<Tooltip <Tooltip
label={ label={
@ -29,7 +35,9 @@ function LLMPicker() {
color={activeModel ? (loadingModel ? "" : "green") : "orange"} color={activeModel ? (loadingModel ? "" : "green") : "orange"}
processing={loadingModel !== null} processing={loadingModel !== null}
> >
<IconRobotFace /> <ActionIcon variant="subtle" onClick={open}>
<IconRobotFace />
</ActionIcon>
</Indicator> </Indicator>
</Tooltip> </Tooltip>
{modelList && ( {modelList && (
@ -37,14 +45,34 @@ function LLMPicker() {
data={modelList} data={modelList}
value={activeModel} value={activeModel}
onChange={(val) => val && selectModel(val)} onChange={(val) => val && selectModel(val)}
placeholder="Select a model..."
searchable searchable
clearable clearable
visibleFrom="sm"
/> />
)} )}
</Group> </Group>
{loadingModel && ( {loadingModel && (
<Progress value={loadingModel.progress} striped animated /> <Progress value={loadingModel.progress} striped animated />
)} )}
<Drawer
offset={8}
radius="md"
opened={opened}
onClose={close}
title="Select model"
position="bottom"
size={200}
>
<Select
data={modelList}
value={activeModel}
onChange={(val) => val && selectModel(val)}
searchable
clearable
/>
</Drawer>
</Stack> </Stack>
); );
} }

View File

@ -53,6 +53,7 @@ const modelList = [
type MLEngineContext = { type MLEngineContext = {
activeModel: string | null; activeModel: string | null;
selectedModel: string | null;
loadingModel: { loadingModel: {
name: string; name: string;
progress: number; progress: number;
@ -67,6 +68,7 @@ type MLEngineContext = {
const MLEngineContext = createContext<MLEngineContext>({ const MLEngineContext = createContext<MLEngineContext>({
activeModel: null, activeModel: null,
selectedModel: null,
loadingModel: null, loadingModel: null,
engine: { current: null }, engine: { current: null },
selectModel: () => {}, selectModel: () => {},
@ -128,6 +130,7 @@ export function MLEngineContextProvider({ children }: { children: ReactNode }) {
? { name: loadingModel, progress: loadingProgress } ? { name: loadingModel, progress: loadingProgress }
: null, : null,
activeModel: runningModel, activeModel: runningModel,
selectedModel,
selectModel: setSelectedModel, selectModel: setSelectedModel,
modelList, modelList,
}} }}

View File

@ -395,72 +395,74 @@ function Organizrr() {
</Group> </Group>
<ScrollArea offsetScrollbars> <ScrollArea offsetScrollbars>
<Group wrap="nowrap" align="start"> <Group wrap="nowrap" align="start">
{form.values.files[activeFile]?.documents.map((d, idx) => ( {form.values.files[activeFile]?.documents.map(
<Stack (d, idx) => (
key={`${d.id}-${idx}`} <Stack
h={500} key={`${d.id}-${idx}`}
mah={500} h={500}
w={300} mah={500}
style={{ cursor: "pointer" }} w={300}
onClick={() => { style={{ cursor: "pointer" }}
setActiveDocumentId(d.id); onClick={() => {
openPreview(); setActiveDocumentId(d.id);
}} openPreview();
> }}
<Group> >
<Text> <Group>
{ <Text>
form.values.documents.find( {
(_d) => _d.id === d.id form.values.documents.find(
)?.file.name (_d) => _d.id === d.id
} )?.file.name
</Text> }
<ActionIcon </Text>
ml="auto" <ActionIcon
variant="subtle" ml="auto"
color="red" variant="subtle"
onClick={(e) => { color="red"
e.stopPropagation(); onClick={(e) => {
form.removeListItem( e.stopPropagation();
`files.${activeFile}.documents`, form.removeListItem(
idx `files.${activeFile}.documents`,
); idx
}} );
> }}
<IconTrash /> >
</ActionIcon> <IconTrash />
</Group> </ActionIcon>
{form.values.documents </Group>
.find((_d) => _d.id === d.id) {form.values.documents
?.file.name.endsWith(".pdf") && ( .find((_d) => _d.id === d.id)
<Box style={{ flexGrow: 1, minHeight: 0 }}> ?.file.name.endsWith(".pdf") && (
<ScrollArea h="100%"> <Box style={{ flexGrow: 1, minHeight: 0 }}>
<Document <ScrollArea h="100%">
file={ <Document
form.values.documents.find( file={
(_d) => _d.id === d.id form.values.documents.find(
)?.file (_d) => _d.id === d.id
} )?.file
className={classNames.pdfPreview} }
> className={classNames.pdfPreview}
<Page pageNumber={1} scale={0.5} /> >
</Document> <Page pageNumber={1} scale={0.5} />
</ScrollArea> </Document>
</Box> </ScrollArea>
)} </Box>
<TextInput
label="Selected pages"
placeholder="1, 3-4, even, odd"
onClick={(e) => e.stopPropagation()}
{...form.getInputProps(
`files.${activeFile}.documents.${idx}.selectedPages`
)} )}
key={form.key( <TextInput
`files.${activeFile}.documents.${idx}.selectedPages` label="Selected pages"
)} placeholder="1, 3-4, even, odd"
/> onClick={(e) => e.stopPropagation()}
</Stack> {...form.getInputProps(
))} `files.${activeFile}.documents.${idx}.selectedPages`
)}
key={form.key(
`files.${activeFile}.documents.${idx}.selectedPages`
)}
/>
</Stack>
)
)}
{form.values.documents {form.values.documents
.find( .find(
(doc) => (doc) =>