Skip to content

feat: Feature Flag Folders for Organization#326

Open
dagangtj wants to merge 2 commits intodatabuddy-analytics:mainfrom
dagangtj:feature/flag-folders
Open

feat: Feature Flag Folders for Organization#326
dagangtj wants to merge 2 commits intodatabuddy-analytics:mainfrom
dagangtj:feature/flag-folders

Conversation

@dagangtj
Copy link

/claim #271

Summary

Implements folder organization for feature flags as requested in issue #271.

Changes

Database Schema

  • Added optional folder text field to flags table
  • Added index on (folder, websiteId) for performance
  • Backward compatible: existing flags work without folders

API Endpoints

  • Updated flags.list to support optional folder filter parameter
  • Updated flags.create to allow setting folder on creation
  • Updated flags.update to allow updating folder field
  • Folder updates don't affect flag evaluation logic

Dashboard UI

  • FolderSidebar: Collapsible folder tree navigation
  • FolderSelector: Dropdown for selecting/creating folders in forms
  • FolderDialog: Modal for creating/renaming folders
  • FlagsList: Groups flags by folder with collapsible sections
  • FlagSheet: Added folder input field in create/edit form

Technical Details

  • Uses simple string field approach (Option A as recommended)
  • Supports nested folders via path separator (e.g., auth/login)
  • Mobile responsive design
  • Uses Phosphor icons as required
  • Follows existing codebase patterns

Screenshots

Will add screenshots after local testing

Checklist

  • Schema change in packages/db/src/drizzle/schema.ts
  • Migration generated successfully
  • Existing flags work without folders (backward compatible)
  • Index added for performance
  • Folder field included in flag responses
  • Folder filtering works in flags.list
  • Folder updates don't affect flag evaluation logic
  • Uses existing UI components
  • Uses Phosphor icons (not Lucide)
  • Mobile responsive

- Add optional folder text field to flags table
- Add index on (folder, websiteId) for performance
- Update API schemas to support folder in list/create/update
- Add folder filtering in flags.list endpoint
- Backward compatible: existing flags work without folder
- Add folder field to flag form schema
- Add folder input in flag create/edit sheet
- Add FolderSidebar component for folder navigation
- Add FolderSelector component for folder selection
- Add FolderDialog component for create/rename folders
- Update FlagsList to group flags by folder with collapsible sections
- Update Flag type to include folder field

Implements databuddy-analytics#271
@vercel
Copy link

vercel bot commented Feb 26, 2026

@dagangtj is attempting to deploy a commit to the Databuddy OSS Team on Vercel.

A member of the Team first needs to authorize it.

@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 26, 2026

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@dosubot
Copy link

dosubot bot commented Feb 26, 2026

Related Documentation

Checked 1 published document(s) in 1 knowledge base(s). No updates required.

How did I do? Any feedback?  Join Discord

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 26, 2026

Greptile Summary

Implements folder organization for feature flags with database schema changes, API support, and UI components.

Key Changes:

  • Added optional folder text field to flags schema with indexed filtering
  • Extended API endpoints to support folder field in create/update/list operations
  • Created three new UI components: FolderDialog, FolderSelector, and FolderSidebar
  • Modified FlagsList to display grouped, collapsible folder sections
  • Added folder input field to flag creation/editing form

Issues Found:

  • Animation implementation uses deprecated framer-motion instead of motion/react and animates layout properties (height), which violates UI performance guidelines
  • Icon-only button missing aria-label for accessibility compliance
  • Otherwise well-structured with proper backward compatibility and type safety

Confidence Score: 4/5

  • This PR is safe to merge with minor style and accessibility fixes needed
  • The implementation is solid with proper schema changes, API validation, and type safety. The folder field is optional and backward compatible. However, there are style guideline violations (using framer-motion instead of motion/react, animating height) and one accessibility issue (missing aria-label). These are non-critical issues that should be fixed but don't block functionality.
  • Pay attention to flags-list.tsx for animation guideline violations and folder-sidebar.tsx for accessibility fix

Important Files Changed

Filename Overview
packages/db/src/drizzle/schema.ts Added optional folder text field to flags table with (folder, websiteId) index for efficient filtering
packages/rpc/src/routers/flags.ts Added folder field to list, create, and update schemas; implements folder filtering in list endpoint
apps/dashboard/app/(main)/websites/[id]/flags/_components/folder-dialog.tsx New dialog component for creating/renaming folders with validation; missing aria-label on button in sidebar
apps/dashboard/app/(main)/websites/[id]/flags/_components/folder-sidebar.tsx New sidebar navigation for folders; icon-only button missing aria-label (accessibility issue)
apps/dashboard/app/(main)/websites/[id]/flags/_components/flags-list.tsx Added folder grouping with collapsible sections; uses incorrect animation package and animates layout properties

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[User Creates/Edits Flag] --> B{FlagSheet Component}
    B --> C[Folder Input Field]
    C --> D{Submit Form}
    
    D --> E[flags.create API]
    D --> F[flags.update API]
    
    E --> G[Validate Schema<br/>folder: string optional]
    F --> G
    
    G --> H[(Database<br/>flags table<br/>folder: text field)]
    H --> I[Index: folder, websiteId]
    
    J[User Views Flags] --> K[flags.list API]
    K --> L{Filter by folder?}
    L -->|Yes| M[WHERE folder = value]
    L -->|No| N[Return all flags]
    
    M --> O[FlagsList Component]
    N --> O
    
    O --> P[Group flags by folder]
    P --> Q[FolderSection Components]
    Q --> R[Collapsible folder UI]
    
    S[FolderSidebar] --> T[Navigate by folder]
    T --> K
    
    U[FolderDialog] --> V[Create/Rename folder]
    V --> E
    
    style H fill:#e1f5ff
    style O fill:#fff4e1
    style B fill:#fff4e1
Loading

Last reviewed commit: f7e2b4b

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

9 files reviewed, 3 comments

Edit Code Review Agent Settings | Greptile

} from "@phosphor-icons/react";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { useMemo } from "react";
import { AnimatePresence, motion } from "framer-motion";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use motion/react instead of framer-motion per UI guidelines

Suggested change
import { AnimatePresence, motion } from "framer-motion";
import { AnimatePresence, motion } from "motion/react";

Context Used: Context from dashboard - .cursor/rules/ui-guidelines.mdc (source)

Comment on lines +455 to +460
isExpanded && "rotate-180"
)}
weight="bold"
/>
</button>
<AnimatePresence initial={false}>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Animating height violates UI guidelines. Only animate compositor props (transform, opacity). Consider using max-height with transform/opacity or a collapsible component that doesn't animate height directly.

Context Used: Context from dashboard - .cursor/rules/ui-guidelines.mdc (source)

Comment on lines +43 to +50
<Button
onClick={onCreateFolder}
size="sm"
variant="ghost"
className="size-8 p-0"
>
<PlusIcon className="size-4" />
</Button>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Icon-only button missing aria-label for accessibility

Suggested change
<Button
onClick={onCreateFolder}
size="sm"
variant="ghost"
className="size-8 p-0"
>
<PlusIcon className="size-4" />
</Button>
<Button
onClick={onCreateFolder}
size="sm"
variant="ghost"
className="size-8 p-0"
aria-label="Create folder"
>
<PlusIcon className="size-4" />
</Button>

Context Used: Context from dashboard - Ultracite Rules - AI-Ready Formatter and Linter (source)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants