Skip to content

Commit

Permalink
feat(ui): interface for the experiment flags (#1724)
Browse files Browse the repository at this point in the history
* feat(ui): experimental ai ui interface

* fix warning;

* [autofix.ci] apply automated fixes

* integrate with local storage

* [autofix.ci] apply automated fixes

* rename

* update

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
  • Loading branch information
wwayne and autofix-ci[bot] authored Mar 28, 2024
1 parent 8dc0548 commit 7b3f532
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
'use client'

import { useEnableCodeBrowserQuickActionBar } from '@/lib/experiment-flags'
import { Switch } from '@/components/ui/switch'

export default function FeatureList() {
const [quickActionBar, toggleQuickActionBar] =
useEnableCodeBrowserQuickActionBar()
return (
<>
{!quickActionBar.loading && (
<div className="flex items-center space-x-4 rounded-md border p-4">
<div className="flex-1 space-y-1">
<p className="text-sm font-medium leading-none">
{quickActionBar.title}
</p>
<p className="text-sm text-muted-foreground">
{quickActionBar.description}
</p>
</div>
<Switch
checked={quickActionBar.value}
onCheckedChange={toggleQuickActionBar}
/>
</div>
)}
</>
)
}
18 changes: 18 additions & 0 deletions ee/tabby-ui/app/(dashboard)/experiments/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Metadata } from 'next'

import FeatureList from './components/feature-list'

export const metadata: Metadata = {
title: 'Experiment Flags'
}

export default function IndexPage() {
return (
<div className="mx-auto flex max-w-xl flex-col gap-3">
<h3 className="scroll-m-20 text-2xl font-semibold tracking-tight">
Experiment Flags
</h3>
<FeatureList />
</div>
)
}
2 changes: 1 addition & 1 deletion ee/tabby-ui/components/ui/switch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const Switch = React.forwardRef<
>(({ className, ...props }, ref) => (
<SwitchPrimitives.Root
className={cn(
'peer inline-flex h-[24px] w-[44px] shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input',
'peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input',
className
)}
{...props}
Expand Down
56 changes: 47 additions & 9 deletions ee/tabby-ui/lib/experiment-flags.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,32 @@
import useLocalStorage from 'use-local-storage'
import { useEffect, useState } from 'react'

const useLocalStorageForExperimentFlag = (
storageKey: string,
defaultValue: boolean
): [boolean, (value: boolean) => void, boolean] => {
const [storageValue, setStorageValue] = useState(defaultValue)
const [loading, setLoading] = useState(true)

useEffect(() => {
const value = localStorage.getItem(storageKey)
if (value) {
setStorageValue(JSON.parse(value))
}
setLoading(false)
}, [])

const upateStorageValue = (newValue: boolean) => {
setStorageValue(newValue)
localStorage.setItem(storageKey, JSON.stringify(newValue))
}

return [storageValue, upateStorageValue, loading]
}

class ExperimentFlag {
constructor(
private storageKey: string,
readonly title: string,
readonly description: string,
readonly defaultValue: boolean
) {}
Expand All @@ -21,36 +45,49 @@ class ExperimentFlag {

class ExperimentFlagFactory {
private storageKey: string
private title: string
private description: string
private defaultValue: boolean

constructor(storageKey: string, description: string, defaultValue?: boolean) {
constructor(
storageKey: string,
title: string,
description: string,
defaultValue?: boolean
) {
this.storageKey = `EXP_${storageKey}`
this.title = title
this.description = description
this.defaultValue = defaultValue ?? false
}

defineGlobalVar() {
return new ExperimentFlag(
this.storageKey,
this.title,
this.description,
this.defaultValue
)
}

defineHook() {
return (): [{ value: boolean; description: string }, () => void] => {
const [storageValue, setStorageValue] = useLocalStorage(
this.storageKey,
this.defaultValue
)
return (): [
{ value: boolean; title: string; description: string; loading: boolean },
() => void
] => {
const [storageValue, setStorageValue, loading] =
useLocalStorageForExperimentFlag(this.storageKey, this.defaultValue)

const toggleFlag = () => {
setStorageValue(!storageValue)
}

return [
{
value: storageValue,
description: this.description
title: this.title,
description: this.description,
loading
},
toggleFlag
]
Expand All @@ -60,7 +97,8 @@ class ExperimentFlagFactory {

const enableCodeBrowserQuickActionBarFactory = new ExperimentFlagFactory(
'enable_code_browser_quick_action_bar',
'Show a quick action popup upon selecting code snippets',
'Quick Action Bar',
'Enable Quick Action Bar to display a convenient toolbar when you select code, offering options to explain the code, add unit tests, and more.',
false
)

Expand Down

0 comments on commit 7b3f532

Please sign in to comment.