Background
Today a list's values can only be seen and edited through the chip input in the Add/Edit List modal —
a ~2-row box where values can't be searched, copied, or edited. Beyond a handful of values, verifying
or maintaining a list is impractical.
The design in one sentence: every list gets its own details page — a list is created with its
metadata in a small modal, and its values are added and managed on the page. Chips are not used
anywhere for values.
Applies to every place that uses this list UI: include/exclude lists on experiments and feature
flags, segment lists, and Global Exclude.
How it works
1. Lists table — where lists are created and opened
The Include/Exclude Lists cards keep their current layout: same columns, toggles, and row actions.
[Add Include List] starts creating a new list (section 2). A list's name is a link to its
details page (section 3), where its values are viewed and managed. The edit action opens the
metadata modal (section 4).
Include Lists
Define include lists of participants... (○ Include All) [Add Include List] ⋮
Type Values Name Enable Actions
────────────────────────────────────────────────────────────────────
schoolId 2,320 Values My schools (on) edit del
──────────
└── link: opens the list's details page (section 3)
(Exclude Lists: same table without the Enable column. Segment-type lists have no values of their
own: their name links to the public segment's page and their edit action opens the segment picker
modal, as today. So across all list types, a name leads to that list's contents and the edit
action opens a small edit modal.)
2. Add List modal — metadata only
Creating a list collects just Type, Name, and Description. Create navigates directly to the new
list's details page, where the values are added.
Add Include List
Type*
[ Group: schoolId ▾ ]
Name*
[ My schools ]
Description (optional)
[ West coast pilot schools ]
Cancel [Create]
3. List Details page — the single home for a list's values
Create lands here. The list starts empty, and the page prompts for values:
Experiments > Math Tutor Experiment > My schools
┌───────────────────────────────────────────────────────────────┐
│ My schools [Edit] [Delete] │
│ Include · Group: schoolId │
│ "West coast pilot schools" │
└───────────────────────────────────────────────────────────────┘
┌───────────────────────────────────────────────────────────────┐
│ Values (0) [Add Values] ⋮ │
│ ─────────────────────────────────────────────────────────── │
│ No values yet. Add values or import a CSV. │
└───────────────────────────────────────────────────────────────┘
[Add Values] opens the entry modal — the only place values are typed or pasted:
Add Values
[ Type or paste values... ] [Add]
Separate values with commas, tabs, or new lines.
┌────────────────────────────────────────────────┐
│ 1014190526892 × │
│ 10855952okoai × │
│ 1085604lds9w3 × │
│ ... (scroll) │
└────────────────────────────────────────────────┘
ⓘ 2 duplicates were skipped
Cancel [Add 128 values]
- Typing a value and pressing Enter (or comma, or clicking [Add]) moves it into the list below;
pasting comma/tab/newline-separated text (e.g. a spreadsheet column) splits it into individual
values. Values keep the order they were typed or pasted in, so a paste can be checked against
its source top-to-bottom, and rows can be removed before confirming.
- Duplicates are reported instead of silently dropped.
With values in place — just added, or opened later from the lists table — the Values section is a
searchable table:
┌───────────────────────────────────────────────────────────────┐
│ Values (2,320) [Search...] [Add Values] ⋮ │
│ ─────────────────────────────────────────────────────────── │
│ Value Actions │
│ 1014190526892 edit del │
│ 10855952okoai edit del │
│ 1085604lds9w3 edit del │
│ ... │
└───────────────────────────────────────────────────────────────┘
- One value per row, with the total count and a search box. Values are plain text, so they
can be selected and copied normally.
- edit fixes a value in place (one-field modal, duplicate-checked) · del removes it
(with confirmation).
- ⋮ = Import CSV (append, or replace — replace shows a count confirmation first, e.g.
"Replace all 2,320 values with 1,980 values from the file?") and Export CSV.
- [Edit] / [Delete] in the header = edit the list's metadata (section 4) / delete the whole list.
- Single-row changes apply immediately (like the enable toggles); bulk operations (CSV replace,
list delete) always confirm first.
4. Edit List modal — same form as the Add List modal
Opened from the edit action in the lists table, or [Edit] on the details page. It is the
same Type/Name/Description form, prefilled. Add and Edit are symmetric, and neither contains values.
Edit Include List
Type*
[ Group: schoolId ▾ ]
Name*
[ My schools ]
Description (optional)
[ West coast pilot schools ]
Cancel [Save]
(Whether Type should stay editable after creation — today changing it resets all values — is a
separate decision, tracked outside this story.)
Typical flows
| Task |
Steps |
| Create a list |
[Add Include List] → Type/Name/Description → Create → lands on the list's page → [Add Values] or Import CSV |
| Open an existing list |
click its name in the lists table → the list's details page |
| Verify a big upload |
Import on the page → count and every value visible as rows; search or export |
| Fix a typo in a value |
Page → search → edit row → correct it |
| Remove values |
Page → search → delete row |
| Spreadsheet round-trip |
Page → Export CSV → edit → Import CSV (replace, with count confirmation) |
| Rename / edit description |
edit action in the lists table, or [Edit] on the page → metadata modal |
Background
Today a list's values can only be seen and edited through the chip input in the Add/Edit List modal —
a ~2-row box where values can't be searched, copied, or edited. Beyond a handful of values, verifying
or maintaining a list is impractical.
The design in one sentence: every list gets its own details page — a list is created with its
metadata in a small modal, and its values are added and managed on the page. Chips are not used
anywhere for values.
Applies to every place that uses this list UI: include/exclude lists on experiments and feature
flags, segment lists, and Global Exclude.
How it works
1. Lists table — where lists are created and opened
The Include/Exclude Lists cards keep their current layout: same columns, toggles, and row actions.
[Add Include List] starts creating a new list (section 2). A list's name is a link to its
details page (section 3), where its values are viewed and managed. The edit action opens the
metadata modal (section 4).
(Exclude Lists: same table without the Enable column. Segment-type lists have no values of their
own: their name links to the public segment's page and their edit action opens the segment picker
modal, as today. So across all list types, a name leads to that list's contents and the edit
action opens a small edit modal.)
2. Add List modal — metadata only
Creating a list collects just Type, Name, and Description. Create navigates directly to the new
list's details page, where the values are added.
3. List Details page — the single home for a list's values
Create lands here. The list starts empty, and the page prompts for values:
[Add Values] opens the entry modal — the only place values are typed or pasted:
pasting comma/tab/newline-separated text (e.g. a spreadsheet column) splits it into individual
values. Values keep the order they were typed or pasted in, so a paste can be checked against
its source top-to-bottom, and rows can be removed before confirming.
With values in place — just added, or opened later from the lists table — the Values section is a
searchable table:
can be selected and copied normally.
(with confirmation).
"Replace all 2,320 values with 1,980 values from the file?") and Export CSV.
list delete) always confirm first.
4. Edit List modal — same form as the Add List modal
Opened from the edit action in the lists table, or [Edit] on the details page. It is the
same Type/Name/Description form, prefilled. Add and Edit are symmetric, and neither contains values.
(Whether Type should stay editable after creation — today changing it resets all values — is a
separate decision, tracked outside this story.)
Typical flows