feat: add folder organization for feature flags (#271)#345
feat: add folder organization for feature flags (#271)#345promisingcoder wants to merge 1 commit intodatabuddy-analytics:mainfrom
Conversation
|
@promisingcoder is attempting to deploy a commit to the Databuddy OSS Team on Vercel. A member of the Team first needs to authorize it. |
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: ASSERTIVE Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
📝 Coding Plan
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment Tip CodeRabbit can use oxc to improve the quality of JavaScript and TypeScript code reviews.Add a configuration file to your project to customize how CodeRabbit runs oxc. |
|
|
Greptile SummaryAdds a folder organization system for feature flags using a simple string field (Option A). The change spans the full stack: a new
Confidence Score: 4/5
Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[FlagsPage] -->|extracts existingFolders| B[FlagSheet]
B -->|folder autocomplete| C{User selects folder?}
C -->|Yes: existing| D[field.onChange folder]
C -->|Yes: new| E[field.onChange trimmed input]
C -->|No / removes| F[field.onChange null]
D --> G[form submit]
E --> G
F --> G
G -->|create| H[RPC flags.create]
G -->|update| I[RPC flags.update]
H -->|folder stored| J[(DB: flags.folder)]
I -->|folder stored| J
J -->|query flags.list| K[FlagsList]
K --> L{Any flag has folder?}
L -->|Yes| M[FolderSection grouped view]
L -->|No| N[Flat list unchanged]
Last reviewed commit: ad29f6f |
| onBlur={() => { | ||
| // Delay to allow click on suggestions | ||
| setTimeout( | ||
| () => setShowFolderSuggestions(false), | ||
| 200 | ||
| ); |
There was a problem hiding this comment.
Suggestion: setTimeout for blur is fragile
Using setTimeout(() => setShowFolderSuggestions(false), 200) to keep the dropdown open long enough for click events to register is a common but fragile pattern — it's a race condition that can fail on slow devices or under heavy CPU load. Consider using onMouseDown with e.preventDefault() on the suggestion buttons instead, which prevents the blur from firing in the first place. That said, this pattern is used elsewhere in the codebase, so this is non-blocking.
| websiteId: input.websiteId || null, | ||
| organizationId: input.organizationId || null, | ||
| environment: input.environment || existingFlag?.[0]?.environment, | ||
| folder: input.folder || null, |
There was a problem hiding this comment.
|| coerces empty string to null
input.folder || null will treat an empty string "" as falsy and convert it to null. While the client currently trims and nullifies empty strings before sending, the createFlagSchema (which spreads flagFormSchema.shape) does allow z.string() — meaning an empty string "" could pass validation. Using input.folder ?? null would be more precise and only coerce undefined/null, matching the pattern you'd want for "no folder". The same applies to the restore path on line 637.
| folder: input.folder || null, | |
| folder: input.folder ?? null, |
Description
Adds a folder system to organize feature flags in the dashboard UI, using Option A (simple string field) as recommended.
/claim #271
Changes (7 files, 292 lines)
Database
packages/db/src/drizzle/schema.ts— Added optionalfoldertext column to flags table + composite index on(websiteId, folder)Shared Schema
packages/shared/src/flags/index.ts— AddedfoldertoflagFormSchemaRPC
packages/rpc/src/routers/flags.ts:flags.list: Added optionalfolderfilter parameter + cache key integrationflags.create: Passesfolderto insertflags.update: Addedfolderto update schemaDashboard UI
flags-list.tsx):FolderSectioncomponent with collapsible headers (Phosphor folder icons, flag count, caret toggle). Groups alphabetically with "Uncategorized" last. Falls back to flat list when no folders exist.flag-sheet.tsx): Autocomplete showing existing folders as suggestions, inline "Create" option for new folders, chip display with remove button.types.ts): Addedfolderto Flag interface andexistingFoldersto FlagSheetProps.page.tsx): Extracts existing folders from flags and passes to FlagSheet.Design Decisions