Refactor repository Commit list
# Context The repository commit list is currently primarily HAML-based and can become difficult to maintain, extend, and optimize. This epic outlines the refactoring and enhancement of the Commit list page, transitioning it into a more robust, performant, and accessible Vue-based solution. The ~frontend team has completed an [initial investigation](https://gitlab.com/gitlab-org/gitlab/-/issues/525172#note_2432352274) into new feature additions/enhancements, backend API requirements, UX improvements, performance considerations, and architecture planning. # Success criteria See https://gitlab.com/groups/gitlab-org/-/epics/17482#note_3102308558 **Job to Be Done and Outcome We're Targeting**\ When investigating the history of changes in a repository, developers and repository managers need to quickly find specific commits using contextual filters — by author, date range, branch, tags, or commit SHA, so they can understand what changed, when, and by whom without leaving the commit list or navigating to multiple pages. The refactored commit list gives developers the power to narrow down thousands of commits to exactly what they are looking for, with commit details surfaced inline without requiring a page navigation. **For the team:** * Commit list is fully migrated to Vue with no regression in existing functionality * Performance baseline established for the new implementation **For customers (measurable after the feature ships):** * Increase in use of filtered search on the commit list page (analytics on filter usage) * Reduction in feedback and requests related to commit list search and navigation limitations # Development Proposal ### Objectives - Improve search functionality (perhaps with something like [filtered search](https://gitlab-org.gitlab.io/gitlab-ui/?path=/docs/base-filtered-search--docs)) (~frontend) - Implement progressive disclosure using the recommended Pajamas design system guidelines (~frontend) - Adopt a clear and maintainable Vue-based architecture (~frontend) - Build API endpoints supporting filtering and pagination, ideally GraphQL (~backend) ### Initial Issues (draft, pending discussions) Note, if the API is not ready by the time we start building the frontend we can exclude API calls from all frontend issues and consider creating a Backend/Frontend integration issue that we can schedule once the backend is ready. - (~frontend) Build frontend boilerplate code (FF, JS entrypoint, empty Vue components, etc) - (~frontend) Integrate `GlFilteredSearch` component + API call (no new filter fields if they're not available) + render commit list - (~frontend) Integrate expandable commit details + API call - (~frontend) Integrate pagination/load more + API call - (~frontend) Add commit list page 1 call to startupJS + performance marks for monitoring ### Architecture <details> <summary>Proposed architecture (frontend)</summary> - [frontend spike](https://gitlab.com/gitlab-org/gitlab/-/issues/525172) **High level overview** - HAML entry point (`#js-project-commits`) to be added to `app/views/projects/commits/show.html.haml` (FF protected) - `#js-project-commits` will conditionally render based on feature flag status (e.g. `:project_commits_refactor`) - Commits list app will be Vue-based - Commit details: requested async and injected into the Vue app via `v-safe-html` (can be refactored later) **Data Flow** - Preload page 1 of commits via StartupJS - Pass static data (i.e. data needed for API calls, RSS feed path, etc via data-attributes) - "Load more"/pagination for subsequent pages - "Expand details" to request commit details - Filtering by ref, author, message **State Management** - Decided against something like Pinia because this is a fairly simple Vue app (we can reconsider later) - Keep the commit list state on the top-level Vue app - Keep commit details state on the commit entry Vue app (requested async via user) - ![commit_list.svg](/-/group/9970/uploads/57188ea4fa950937fa456286352ee982/commit_list.svg) </details> # Design Proposal Full proposal https://gitlab.com/groups/gitlab-org/-/epics/17482#note_2549379250 | Scoped MVC https://gitlab.com/groups/gitlab-org/-/epics/17482#note_2608137058 This is the design proposal summarizing the improvements being made to the commit list during this refactor. This is the MVC design. See https://gitlab.com/groups/gitlab-org/-/epics/17482#note_2549379250 for ideal long-term proposal. [:art: Figma](https://www.figma.com/design/eq2nf3B8MhB9xKrC0VzbPf/branch/3jjv6jJrQBKnrW4yxm6XRe/Repository?m=auto&node-id=6706-37741&t=yFDHnrlTv1lbLPWV-1) <table> <tr> <th></th> <th>Screen</th> <th>Notes</th> </tr> <tr> <td>Default</td> <td> ![1.1 Proposal - default.jpg](/uploads/b9722dfc0fa01e84b55bb1c20e0a2149/1.1_Proposal_-_default.jpg) </td> <td> * Breadcrumb behavior remains the same as in the old Commits page. Breadcrumbs link to the Commits page for the respective file/directory. * We should keep an eye on user feedback about whether or not users want more density on the Commits page / want to see more commits per page. </td> </tr> <tr> <td>Commit drawer</td> <td> ![1._Only_show_description.jpg](/uploads/7f5250c0d7f7e0ec339541a204b8bebf/1._Only_show_description.jpg){width="844" height="600"} </td> <td> * The commit message is shown when users expand the drawer. * Hovering over MR link will show MR popover (Ex: hover https://gitlab.com/gitlab-org/gitlab/-/merge_requests/224495) * Hovering over username will show username popover (Ex: hover @alyssatrinh) * An information-rich version of this [Attribute list](https://design.gitlab.com/components/attribute-list) drawer was presented in https://gitlab.com/groups/gitlab-org/-/epics/17482#note_2549379250, however we currently do not pass the necessary metadata to achieve this at the moment for the MVC https://gitlab.com/groups/gitlab-org/-/epics/17482#note_2608137058. </td> </tr> <tr> <td>Menus</td> <td> ![2.1 Proposal - menus default branch.jpg](/uploads/5becf3b1c184f04324ff53d086dc0baf/2.1_Proposal_-_menus_default_branch.jpg) ![2.2 Proposal - sort by.jpg](/uploads/68cefa8f7f2caae35f35cc1aa5153d97/2.2_Proposal_-_sort_by.jpg) </td> <td> * The `Browse files` and `Commits feed` button will be moved into the overflow menu. * When users hover over the file button next to each individual commit, the tooltip text should be updated to `Browse commit files` * `Sort direction` can be implemented post-MVC. Example of sort direction can be found on the Issues page. * Users will be allowed to set pagination interval to see more commits per page. </td> </tr> <tr> <td>Non-default branch</td> <td> ![2.3 Proposal - nondefault branch overflow menu.jpg](/uploads/c8f68cac404dbc36f41919f2cf68139e/2.3_Proposal_-_nondefault_branch_overflow_menu.jpg) ![2.4 Proposal - menus nondefault branch open mr.jpg](/uploads/96d01cc04cf3e9d0dc138b359942a301/2.4_Proposal_-_menus_nondefault_branch_open_mr.jpg) </td> <td> * The `View open merge request` button in the old Commits page will be replaced by the open MRs badge implemented in https://gitlab.com/gitlab-org/gitlab/-/issues/520125. </td> </tr> <tr> <td>Pagination</td> <td> ![pagination.jpg](/uploads/2e50b00b948dc92ce304bc91215adb18/pagination.jpg) </td> <td> * Add [Keyset Pagination](https://gitlab-org.gitlab.io/gitlab-ui/?path=/story/base-keyset-pagination--default) with a selector to allow users to choose how many elements they would like to load at once. https://gitlab.com/groups/gitlab-org/-/epics/17482#note_2461050982 * This allows users to set the interval at which they would like to load, which can increase #efficiency * The commit list is ordered sequentially by age, so my assumption is there's less user value in linking to a specific "page." If pagination is desired, that's something we can add in a future iteration. * See [Issues](https://gitlab.com/gitlab-org/gitlab/-/issues/?sort=created_asc&state=opened&first_page_size=100) page for example of pagination: ![issues-pagination.png](https://gitlab.com/-/group/9970/uploads/7e56c8cd1bd1951b4dcc6f1e54c2462c/issues-pagination.png){width="442" height="252"} </td> </tr> <tr> <td>Date range filter</td> <td> ![4.1 Proposal - date range single value filter select.jpg](/-/group/9970/uploads/b4165f249a39700558167cb9a4336bad/4.1_Proposal_-_date_range_single_value_filter_select.jpg) ![4.2 Proposal - date range single value filter select calendar.jpg](/-/group/9970/uploads/c126c7a0f4d0299c7d4e0549f6c74441/4.2_Proposal_-_date_range_single_value_filter_select_calendar.jpg) ![4.3 Proposal - date range single value filter populated.jpg](/-/group/9970/uploads/5458d8af5e398fc4cd1fab15a1a9b9c1/4.3_Proposal_-_date_range_single_value_filter_populated.jpg) ![4.4 Proposal - date range multiple single value filters populated.jpg](/-/group/9970/uploads/d7de8a5a98c77b711e65627343c6ee12/4.4_Proposal_-_date_range_multiple_single_value_filters_populated.jpg) </td> <td> * For an MVC iteration, the "Committed after" and "Committed before" filters will allow users to filter by date. See https://gitlab.com/groups/gitlab-org/-/epics/17482#note_2565131681. * See [Code \> Merge requests](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/?sort=created_date&state=opened&first_page_size=20) for an example of a date picker that hacks date range with 2 individual date fields ![mr-date-filter.png](https://gitlab.com/-/group/9970/uploads/69de951bf7bdebae667e44674fc1b6fa/mr-date-filter.png){width="978" height="520"} * The ideal UX would be to build a component variation of the date picker that allows users to select a date range. This is out-of-scope for the MVC but can be considered in future iterations in https://gitlab.com/gitlab-org/gitlab/-/issues/554011. </td> </tr> </table> #### Mobile breakpoint See Option 1 in https://gitlab.com/groups/gitlab-org/-/epics/17482#note_2611078691 | https://gitlab.com/gitlab-org/gitlab/-/work_items/579130 <table> <tr> <th></th> <th>Screen</th> <th>Notes</th> </tr> <tr> <td>Default</td> <td> ![M1. default.jpg](/uploads/263d1a8e9fb8418a5b44028e0331d41e/M1._default.jpg) </td> <td> * "Verified" badge and tag is using a smaller, mobile-friendly version of the badge (16px tall). I don't see this in Pajamas, however, we are currently using a smaller badge on mobile on the current [Commits](https://gitlab.com/gitlab-org/gitlab/-/commits/master) page. </td> </tr> <tr> <td>Interactions</td> <td> ![M1. expanded.jpg](/uploads/dbfa7660a2f8a3d3504c4c27867eb5e1/M1._expanded.jpg) </td> <td> * See [Issues page](https://gitlab.com/gitlab-org/gitlab/-/issues) for an example of how the crud component expands/collapses on mobile * Clicking on the commit title will bring users to the commits detail page (see click state in blue) </td> </tr> <tr> <td>Breadcrumb overflow</td> <td> ![M3. breadcrumb overflow.jpg](/uploads/679c298b299106c131b5bccafc123acf/M3._breadcrumb_overflow.jpg) </td> <td> * The breadcrumb will appear by default to the right of the branch selector * If there is no more space, the breadcrumbs will fall onto a new line. * See [Repository page](https://gitlab.com/gitlab-org/gitlab/-/tree/master) for an example of how this functions. </td> </tr> </table> ### Search filters Add a [filtered search](https://gitlab-org.gitlab.io/gitlab-ui/?path=/docs/base-filtered-search--docs) to make it more efficient for users to find the commits they are looking for. See https://gitlab.com/groups/gitlab-org/-/epics/17482#note_2460965124. <table> <tr> <th>Current search fields</th> <th>Proposed search fields to add</th> </tr> <tr> <td> Currently users can filter the commit list by: * `author` * `message` * `ref` (branch, tag, commit sha) * `path` * `committed_before` * `committed_after` Additionally they can limit and offset each request * `limit` * `offset` </td> <td> In addition to the current search fields, we would like to add (priority in bold): * `Committed after` / `Committed before` (date range) **High** * `tags/branches with wildcards` **Medium** * `commit sha` **Low** * `committer` **Low** * `badge` **Low** * `pipeline status` **Low**. There may be technical restraints from the CI/CD team side https://gitlab.com/groups/gitlab-org/-/epics/17482#note_2462748058 In additional to the offset pagination we would also like cursor based pagination * `next_cursor` in response -\> `pagination_params.page_token` in next request </td> </tr> </table> # Out-of-scope #### Filter fields The following data fields for search field filters are considered out-of-scope at this time, but may be considered in the future: * `code search` The global search team just added https://gitlab.com/gitlab-org/gitlab/-/issues/525326+ to the global advanced search. Being able to search by exact piece of code could be useful (but probably with high LOE for implementation, heavy performance cost). * `file change` searching by file change could be useful if users are looking for specific changes. Related to code search. (Is this covered by the `path` argument used when viewing history of a file?) * `merge commits` Include or exclude merge commits. Might be useful for refactors where the commit list might be polluted. * `signed` whether or not the commit is signed, or not signed. This may or may not be covered by the `badge` filter. Our docs for [Signed commits](https://docs.gitlab.com/user/project/repository/signed_commits/) say `Depending on the verification status of the signature, signed commits display either a Verified or Unverified badge` but I'm not sure if the element is actually a badge. * `file` allow users to search for files. Even though the Commits page is currently scoped to a specific file/directory, filtering for a specific file would be faster for users than navigating the breadcrumbs or repository. See https://gitlab.com/groups/gitlab-org/-/epics/17482#note_2512884189. * `merge request state`? See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/191169 #### Other * Attribute list with metadata https://gitlab.com/groups/gitlab-org/-/epics/17482#note_2549379250 * Serving an information-rich commit preview experience using the [Attribute list](https://design.gitlab.com/components/attribute-list) component was the original proposal. However, we do not currently fetch the necessary metadata to implement this experience https://gitlab.com/groups/gitlab-org/-/epics/17482#note_2608137058. * Date range picker with range component https://gitlab.com/gitlab-org/gitlab/-/issues/554011 * In the first iteration of the date range filter, `Committed before` and `Committed after` will appear as separate filters. The ideal UX would be to build a component variation of the date picker that allows users to select a date range.
epic