Skip to main content
Glama
reflagcom

Bucket Feature Flags MCP Server

Official
by reflagcom
Flags.tsx4.36 kB
import { Fragment, h } from "preact"; import { Switch } from "./Switch"; import { FlagItem } from "./Toolbar"; const isFound = (flagKey: string, searchQuery: string | null) => { return flagKey.toLocaleLowerCase().includes(searchQuery ?? ""); }; export function FlagsTable({ flags, searchQuery, appBaseUrl, setIsEnabledOverride, }: { flags: FlagItem[]; searchQuery: string | null; appBaseUrl: string; setIsEnabledOverride: (key: string, isEnabled: boolean | null) => void; }) { const hasFlags = flags.length > 0; const hasShownFlags = flags.some((flag) => isFound(flag.flagKey, searchQuery), ); // List flags that match the search query first then alphabetically const searchedFlags = searchQuery === null ? flags : [...flags].sort((a, b) => { const aMatches = isFound(a.flagKey, searchQuery); const bMatches = isFound(b.flagKey, searchQuery); // If both match or both don't match, sort alphabetically if (aMatches === bMatches) { const aStartsWith = a.flagKey .toLocaleLowerCase() .startsWith(searchQuery); const bStartsWith = b.flagKey .toLocaleLowerCase() .startsWith(searchQuery); // If one starts with search query and the other doesn't, prioritize the one that starts with it if (aStartsWith && !bStartsWith) return -1; if (bStartsWith && !aStartsWith) return 1; // Otherwise sort alphabetically return a.flagKey.localeCompare(b.flagKey); } // Otherwise, matching flags come first return aMatches ? -1 : 1; }); return ( <Fragment> {(!hasFlags || !hasShownFlags) && ( <div class="flags-table-empty"> No flags {hasFlags ? `matching "${searchQuery}"` : "found"} </div> )} <table class="flags-table"> <tbody> {searchedFlags.map((flag, index) => ( <FlagRow key={flag.flagKey} appBaseUrl={appBaseUrl} flag={flag} index={index} isNotVisible={ searchQuery !== null && !isFound(flag.flagKey, searchQuery) } setEnabledOverride={(override) => setIsEnabledOverride(flag.flagKey, override) } /> ))} </tbody> </table> </Fragment> ); } function FlagRow({ setEnabledOverride, appBaseUrl, flag, index, isNotVisible, }: { flag: FlagItem; appBaseUrl: string; setEnabledOverride: (isEnabled: boolean | null) => void; index: number; isNotVisible: boolean; }) { const isEnabledOverride = flag.isEnabledOverride !== null; return ( <tr key={flag.flagKey} class={["flag-row", isNotVisible ? "not-visible" : undefined].join(" ")} > <td class="flag-name-cell"> <a class="flag-link" href={`${appBaseUrl}/env-current/flags/by-key/${flag.flagKey}`} rel="noreferrer" tabIndex={index + 1} target="_blank" > {flag.flagKey} </a> </td> <td class="flag-reset-cell"> {isEnabledOverride ? ( <Reset setEnabledOverride={setEnabledOverride} tabIndex={index + 1} /> ) : null} </td> <td class="flag-switch-cell"> <Switch checked={flag.isEnabledOverride ?? flag.isEnabled} tabIndex={index + 1} onChange={(e) => { const isChecked = e.currentTarget.checked; setEnabledOverride(!isEnabledOverride ? isChecked : null); }} /> </td> </tr> ); } export function FlagSearch({ onSearch }: { onSearch: (val: string) => void }) { return ( <input class="search-input" placeholder="Search flags" tabIndex={0} type="search" autoFocus onInput={(s) => onSearch(s.currentTarget.value)} /> ); } function Reset({ setEnabledOverride, ...props }: { setEnabledOverride: (isEnabled: boolean | null) => void; } & h.JSX.HTMLAttributes<HTMLAnchorElement>) { return ( <a class="reset" href="" onClick={(e) => { e.preventDefault(); setEnabledOverride(null); }} {...props} > reset </a> ); }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/reflagcom/bucket-javascript-sdk'

If you have feedback or need assistance with the MCP directory API, please join our Discord server