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
31 changes: 31 additions & 0 deletions web-client/src/components/ui/switch.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import * as React from "react"
import { Switch as SwitchPrimitive } from "radix-ui"

import { cn } from "@/lib/utils"

function Switch({
className,
size = "default",
...props
}: React.ComponentProps<typeof SwitchPrimitive.Root> & {
size?: "sm" | "default"
}) {
return (
<SwitchPrimitive.Root
data-slot="switch"
data-size={size}
className={cn(
"peer group/switch relative inline-flex shrink-0 items-center rounded-none border transition-all outline-none after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/30 aria-invalid:border-destructive aria-invalid:ring-2 aria-invalid:ring-destructive/20 data-[size=default]:h-4.5 data-[size=default]:w-8.25 data-[size=sm]:h-3.5 data-[size=sm]:w-6.25 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:border-primary data-checked:bg-primary data-unchecked:border-input/50 data-unchecked:bg-input data-disabled:cursor-not-allowed data-disabled:opacity-50",
className
)}
{...props}
>
<SwitchPrimitive.Thumb
data-slot="switch-thumb"
className="pointer-events-none block bg-background ring-0 transition-transform group-data-[size=default]/switch:size-3.5 group-data-[size=sm]/switch:size-2.5 data-checked:translate-x-[calc(100%+2px)] dark:data-checked:bg-primary-foreground data-unchecked:translate-x-0.25 dark:data-unchecked:bg-foreground"
/>
</SwitchPrimitive.Root>
)
}

export { Switch }
10 changes: 6 additions & 4 deletions web-client/src/features/helper/api/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,19 @@ export function useHelperHello() {
export function useGenerateMemberReport(memberId: string) {
const qc = useQueryClient()

return useMutation<void, Error, void>({
mutationFn: () => helperClient.post(`/reports/member/${memberId}`).then(() => undefined),
return useMutation<void, Error, boolean | undefined>({
mutationFn: (useLocal) =>
helperClient.post(`/reports/member/${memberId}`, { uselocal: useLocal }).then(() => undefined),
onSuccess: () => qc.invalidateQueries({ queryKey: helperKeys.memberReports(memberId) }),
})
}

export function useGenerateTeamReport(teamId: string) {
const qc = useQueryClient()

return useMutation<void, Error, void>({
mutationFn: () => helperClient.post(`/reports/team/${teamId}`).then(() => undefined),
return useMutation<void, Error, boolean | undefined>({
mutationFn: (useLocal) =>
helperClient.post(`/reports/team/${teamId}`, { uselocal: useLocal }).then(() => undefined),
onSuccess: () => qc.invalidateQueries({ queryKey: helperKeys.teamReports(teamId) }),
})
}
Expand Down
2 changes: 1 addition & 1 deletion web-client/src/features/helper/model/useReportViewModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export function useReportViewModel() {
rows,
isLoading: (isTrainer && teamsQuery.isLoading) || query.isLoading,
isError: query.isError,
generate: () => generate.mutate(),
generate: (useLocal?: boolean) => generate.mutate(useLocal),
isGenerating: generate.isPending,
generateError: generate.error,
listKey,
Expand Down
24 changes: 20 additions & 4 deletions web-client/src/features/helper/pages/HelperPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
} from '@/components/ui/alert-dialog'
import { Button } from '@/components/ui/button'
import { Card, CardContent } from '@/components/ui/card'
import { Label } from '@/components/ui/label'
import { PageHeader } from '@/components/ui/page-header'
import { RowActionButton, RowActions } from '@/components/ui/row-action-button'
import { Separator } from '@/components/ui/separator'
Expand All @@ -23,6 +24,7 @@ import {
SheetTitle,
} from '@/components/ui/sheet'
import { Skeleton } from '@/components/ui/skeleton'
import { Switch } from '@/components/ui/switch'
import { serverErrorMessage } from '@/lib/server-error'
import { useHelperUiStore } from '../model/helperUiStore'
import {
Expand Down Expand Up @@ -54,10 +56,11 @@ export function HelperPage() {
const [generated, setGenerated] = useState(false)
const [deleteError, setDeleteError] = useState<string | null>(null)
const [deleteTargetId, setDeleteTargetId] = useState<string | null>(null)
const [useLocalLlm, setUseLocalLlm] = useState(false)

const onGenerate = () => {
setGenerated(false)
generate()
generate(useLocalLlm)
// The result is async (the POST returns 202 with no body); confirm we kicked it off.
setGenerated(true)
}
Expand Down Expand Up @@ -116,9 +119,22 @@ export function HelperPage() {
<p className="text-body-sm text-destructive">{generateError.message}</p>
)}
</div>
<Button onClick={onGenerate} disabled={isGenerating}>
{isGenerating ? 'Starting…' : 'Generate report'}
</Button>
<div className="flex shrink-0 items-center gap-3">
<div className="flex items-center gap-2">
<Switch
id="use-local-llm"
checked={useLocalLlm}
onCheckedChange={setUseLocalLlm}
disabled={isGenerating}
/>
<Label htmlFor="use-local-llm" className="text-body-sm text-text-secondary">
Use local LLM
</Label>
</div>
<Button onClick={onGenerate} disabled={isGenerating}>
{isGenerating ? 'Starting…' : 'Generate report'}
</Button>
</div>
</div>

<Separator />
Expand Down
Loading