Navigate repo with a file tree
# Context
A file tree view has been requested quite a number of times ("Especially the file tree view is simply a must-have for navigation" [via Reddit](https://www.reddit.com/r/programming/comments/471he5/gitlab_85_released/d0ae85g)) and was even implemented by the community as a browser extension [Octotree](https://github.com/buunguyen/octotree).
Unfortunately this extension no longer works for GitLab due to design changes, nor did it support private GitLab projects.
Community expectations were also set that Octotree functionality would be integrated into GitLab in https://gitlab.com/gitlab-org/gitlab-ce/issues/13723
A version of this has been partially implemented within https://gitlab.com/gitlab-org/gitlab-ce/issues/31890 (pre-alpha accessible by creating a cookie `new_repo` with the value `true`).
# Design proposal
Implement a file tree view in the file list to make browsing and reading files in the web interface easier. It should:
1. allow the sub-directories to be expanded and collapsed as a file tree
2. show the file tree while viewing a file
The grey background is to just illustrate a placeholder that we would use the same tree component that exists in the MR view.
[:art: Figma](https://www.figma.com/design/eq2nf3B8MhB9xKrC0VzbPf/branch/O5yS3uus7k4Z4BkRyV1DlE/Repository?m=auto&node-id=5561-5384&t=LWOMoLEbZUZsgoQt-1)
#### Directory
<table>
<tr>
<th>Collapsed</th>
<th>Expanded</th>
</tr>
<tr>
<td>

</td>
<td>


</td>
</tr>
</table>
#### File
| Collapsed | Expanded |
|-----------|----------|
|  |  |
#### **Default state & first time experience**
<table>
<tr>
<th>Default state & first time experience</th>
<th>Reference: Issues popover</th>
</tr>
<tr>
<td>
{width="889" height="630"}
* First time user sees the file tree: Show a [popover](https://design.gitlab.com/patterns/feature-discovery#patterns-for-initial-prompts) to introduce the feature
* File tree is open by default
* Store the user's most recent choice and persist that choice when browsing the repository
* Collect data on whether or not users use the file tree browser
* See https://gitlab.com/groups/gitlab-org/-/epics/17781#note_2673324349
</td>
<td>
{width="344" height="246"}
[Pajamas feature discovery documentation](https://design.gitlab.com/patterns/feature-discovery#patterns-for-initial-prompts)
</td>
</tr>
</table>
#### **Search**
See https://gitlab.com/gitlab-org/gitlab/-/issues/543753#note_2804696436 | https://gitlab.com/gitlab-org/gitlab/-/work_items/581901
Use the global `Find file` search functionality, however present the search in a panel that is attached to the search field.
| Default | Search |
|---------|--------|
| {width="844" height="600"} | {width="844" height="600"} |
#### Viewports
See https://gitlab.com/gitlab-org/gitlab/-/work_items/583851
<table>
<tr>
<th>Viewport</th>
<th>Reference: MR Rapid diffs file tree</th>
<th>Current</th>
<th>Proposed</th>
</tr>
<tr>
<td>
xs
\<576px
</td>
<td>Mobile. Visible as panel.</td>
<td>Mobile. Hidden.</td>
<td>
**Mobile. Panel.**
{width=356 height=600}
* To close the panel, click on the file tree button or click anywhere outside the panel https://gitlab.com/gitlab-org/gitlab/-/work_items/581018
</td>
</tr>
<tr>
<td>
sm
≥576px
</td>
<td>Mobile. Visible as panel.</td>
<td>Mobile. Hidden.</td>
<td>
**Mobile. Panel.**
{width=356 height=600}
* To close the panel, click on the file tree button or click anywhere outside the panel https://gitlab.com/gitlab-org/gitlab/-/work_items/581018
</td>
</tr>
<tr>
<td>
md
≥768px
</td>
<td>≥800px. Side-by-side.</td>
<td>Tablet. Panel.</td>
<td>
**Side-by-side**
{width=503 height=600}
* Default width of the file tree browser + left padding is 280px on side-by-side view. On a 768px screen, that would leave a width of 456px for the primary content.
* The content is a bit squished. That being said, there are some UI elements that aren't well optimized for this viewport (Find file button, most recent commit info well).
* This is borderline not a great UX. However, side-by-side would be more consistent with the rapid diffs file tree, and we can gather data on whether or not users prefer navigation with the file tree or file list and adjust as needed.
</td>
</tr>
<tr>
<td>
lg
≥992px
</td>
<td>Side-by-side</td>
<td>Panel</td>
<td>
**Side-by-side**
{width=565 height=600}
* Default width of the file tree browser + left padding is 280px on side-by-side view. On a 992px screen, that would leave a width of 612px for the primary content.
* The content isn't too squished and is still usable with a side-by-side file tree browser.
</td>
</tr>
<tr>
<td>
xl
≥1200px
</td>
<td>Desktop. Side-by-side.</td>
<td>Desktop. Side-by-side.</td>
<td>
**Desktop. Side-by-side.**
{width=900 height=504}
</td>
</tr>
</table>
#### Interactions
* First time user experience
* Show a dismissible [popover](https://design.gitlab.com/patterns/feature-discovery#patterns-for-initial-prompts) to introduce the feature.
* Default
* By default, the file tree navigation panel is open by default. The user's most recent choice is stored and persisted. See https://gitlab.com/groups/gitlab-org/-/epics/17781#note_2673324349.
* Selected state
* Use the selected state currently present on the Merge Request \> Changes file tree.
* Filter file bar
* This bar allows users to filter the tree by extension, or file name. This filter bar currently exists in the Merge Request \> Changes file tree, and should follow the same behavior.
* Note that when users filter, the formatting of the tree changes to list view instead of tree view. This is odd and should be updated in a later iteration if possible (see Out-of-Scope below).
* Navigation
* The file tree will dynamically mirror the state of the file list. If a directory is open in the file list, it will also be open in the file tree. See https://gitlab.com/gitlab-org/gitlab/-/issues/525169#note_2445592460
* For example if a user clicks into a directory in the file list:
* The file list will open that directory (current)
* The file tree will have that directory selected, and open
* Keyboard shortcuts https://gitlab.com/gitlab-org/gitlab/-/issues/545036#note_2657505404
* <kbd>f</kbd> will always open file browser and focus the search field
* <kbd>shift</kbd>+<kbd>f</kbd> will only toggle file browser visibility
* Whenever filter is in focus, `↓` key navigates to the first item in the list. Users can use `↓↑` arrow keys to navigate the filter list. See example gitlab-ui!5061 (merged).
* Pagination
* Pagination will follow a similar pattern to what the repository file list is currently using.
* After 1000 items, a `Show more` button will display. When `Show more` is clicked, the next 1000 items will be loaded in batches of 100.
* See https://gitlab.com/groups/gitlab-org/-/epics/17781#note_2492791233
#### MR page file filter updates
* Slight updates will be made to the Merge Request \> Changes file filter to improve the file filter field in https://gitlab.com/gitlab-org/gitlab/-/issues/535503.
#### Links / references
- https://gitlab.com/gitlab-org/gitlab-ce/issues/13723
# Documentation blurb
#### Overview
A file tree view will makes it easier to browse the contents of a repository, a common task, reducing the need to pull a projects source code locally simply to read it.
This feature will provide a persistent file tree view that allows the repositories contents to be browsed as a tree, and provide an improved navigation experience because the user will not have to switch between the file list and file view, which is disorienting.
# Use cases
Thanks @victorwu for enumerating a number of scenarios here: https://gitlab.com/gitlab-org/gitlab-ce/issues/13723#note_24460171
# Feature checklist
Make sure these are completed before closing the issue, with a link to the relevant commit.
- [ ] [Feature assurance](https://about.gitlab.com/handbook/product/#feature-assurance)
- [ ] Documentation
- [ ] Added to [features.yml](https://gitlab.com/gitlab-com/www-gitlab-com/blob/master/data/features.yml)
# Out-of-scope
* Project overview page will not show the file tree at this time due to layout constraints https://gitlab.com/gitlab-org/gitlab/-/issues/19530#note_2432121108. If we get a signal from users this is desired, that can added in a future iteration.
* When users type an input into the filter bar in Merge Request \> Changes, the formatting changes from Tree view to List view. In a later iteration, the file structure should be preserved so that users filtering the file tree should not face formatting changes.
* Will handle the scenario of displaying the tree while editing in a separate issue. The reason for this is that the layout of the edit view is very different than the viewing and we may need to address this at the same time.
epic