Commit 907a6aae authored by Ezekiel Kigbo's avatar Ezekiel Kigbo

Updated layout for various breakpoints

Updated translations

Adds sort direction dropdown

Allows the project list sorting direction to be changed,
available options can be sorted ascending or descending.
Implements the changes from the UX review.
parent 19cd9cc9
...@@ -1448,6 +1448,14 @@ pre.light-well { ...@@ -1448,6 +1448,14 @@ pre.light-well {
} }
.project-filters { .project-filters {
.row-content-block {
border-top: 0;
}
.btn svg {
color: $gl-gray-700;
}
.button-filter-group { .button-filter-group {
.btn { .btn {
width: 96px; width: 96px;
...@@ -1462,9 +1470,144 @@ pre.light-well { ...@@ -1462,9 +1470,144 @@ pre.light-well {
} }
} }
@include media-breakpoint-down(sm) { .filter-with-icon {
border-radius: 3px 0 0 3px;
}
.filtered-search-wrapper {
flex-wrap: nowrap;
flex-direction: row;
}
.filtered-search-dropdown {
width: auto;
flex-direction: row;
align-items: center;
}
.filtered-search,
.filtered-search-nav,
.filtered-search-dropdown {
display: flex;
min-width: auto;
margin: 0;
}
.filtered-search-dropdown-label {
padding: 0 8px 0 16px;
font-weight: bold;
min-width: 76px;
}
.filtered-search {
margin: 0 0 0 16px;
min-width: 30%;
width: 100%;
flex: 1 1 0;
.project-filter-form .project-filter-form-field {
padding-right: 8px;
}
}
.filtered-search,
.filtered-search-dropdown {
.btn-group {
width: 100%;
}
.qa-reverse-sort {
max-width: 38px;
}
}
.filtered-search-box {
border-radius: 3px 0 0 3px;
}
@include media-breakpoint-down(lg) {
.filtered-search {
min-width: 15%;
.project-filter-form-field {
min-width: 150px;
}
}
.extended-filtered-search.filtered-search {
margin-left: 0;
min-width: 65%;
}
}
@include media-breakpoint-down(md) {
.filtered-search {
margin: 0 0 8px 16px;
min-width: 30%;
}
.filtered-search-nav {
margin: 0 0 8px;
}
.filtered-search-wrapper {
flex-wrap: wrap;
}
.filtered-search-dropdown {
width: 50%;
}
.filtered-search-dropdown .dropdown {
display: flex;
flex: 1 1 0;
}
.filtered-search-dropdown .dropdown button {
width: 100%;
}
}
@include media-breakpoint-down(xs) {
.dropdown-menu-toggle { .dropdown-menu-toggle {
width: 100%; width: 100%;
} }
.filtered-search-wrapper {
display: flex;
flex-flow: column nowrap;
}
.filtered-search,
.filtered-search-nav,
.filtered-search-dropdown {
flex: 1 1 0;
width: 100%;
}
.filtered-search {
margin-left: 0;
}
.filtered-search-box {
margin: 0;
}
.filtered-search-nav .nav-block {
width: 100%;
}
.filtered-search-dropdown {
margin: 0 0 8px;
}
.filtered-search-dropdown-label {
padding-left: 0;
}
} }
}
\ No newline at end of file
}
...@@ -31,14 +31,13 @@ module SortingHelper ...@@ -31,14 +31,13 @@ module SortingHelper
} }
end end
# TODO: stars_asc doesnt seem to work
def projects_sort_options_hash def projects_sort_options_hash
options = { options = {
sort_value_latest_activity => sort_title_latest_activity, sort_value_latest_activity => sort_title_latest_activity,
sort_value_name => sort_title_name,
sort_value_oldest_activity => sort_title_oldest_activity,
sort_value_oldest_created => sort_title_oldest_created,
sort_value_recently_created => sort_title_recently_created, sort_value_recently_created => sort_title_recently_created,
sort_value_most_stars => sort_title_most_stars sort_value_name => sort_title_name,
sort_value_most_stars => sort_title_stars
} }
if current_controller?('admin/projects') if current_controller?('admin/projects')
...@@ -48,6 +47,32 @@ module SortingHelper ...@@ -48,6 +47,32 @@ module SortingHelper
options options
end end
def projects_sort_option_titles
{
sort_value_latest_activity => sort_title_latest_activity,
sort_value_recently_created => sort_title_recently_created,
sort_value_name => sort_title_name,
sort_value_most_stars => sort_title_stars,
sort_value_oldest_activity => sort_title_latest_activity,
sort_value_oldest_created => sort_title_recently_created,
sort_value_name_desc => sort_title_name,
sort_value_most_stars_asc => sort_title_stars
}
end
def projects_reverse_sort_options_hash
{
sort_value_latest_activity => sort_value_oldest_activity,
sort_value_recently_created => sort_value_oldest_created,
sort_value_name => sort_value_name_desc,
sort_value_most_stars => sort_value_most_stars_asc,
sort_value_oldest_activity => sort_value_latest_activity,
sort_value_oldest_created => sort_value_recently_created,
sort_value_name_desc => sort_value_name,
sort_value_most_stars_asc => sort_value_most_stars
}
end
def groups_sort_options_hash def groups_sort_options_hash
{ {
sort_value_name => sort_title_name, sort_value_name => sort_title_name,
...@@ -194,6 +219,22 @@ module SortingHelper ...@@ -194,6 +219,22 @@ module SortingHelper
end end
end end
def project_sort_direction_button(sort_value)
link_class = 'btn btn-default has-tooltip reverse-sort-btn qa-reverse-sort'
reverse_sort = projects_reverse_sort_options_hash[sort_value]
if reverse_sort
reverse_url = filter_projects_path(sort: reverse_sort)
else
reverse_url = '#'
link_class += ' disabled'
end
link_to(reverse_url, type: 'button', class: link_class, title: 'Sort direction') do
sprite_icon("sort-#{issuable_sort_icon_suffix(sort_value)}", size: 16)
end
end
# Titles. # Titles.
def sort_title_access_level_asc def sort_title_access_level_asc
s_('SortOptions|Access level, ascending') s_('SortOptions|Access level, ascending')
...@@ -327,6 +368,10 @@ module SortingHelper ...@@ -327,6 +368,10 @@ module SortingHelper
s_('SortOptions|Most stars') s_('SortOptions|Most stars')
end end
def sort_title_stars
s_('SortOptions|Stars')
end
def sort_title_oldest_last_activity def sort_title_oldest_last_activity
s_('SortOptions|Oldest last activity') s_('SortOptions|Oldest last activity')
end end
...@@ -472,6 +517,11 @@ module SortingHelper ...@@ -472,6 +517,11 @@ module SortingHelper
'stars_desc' 'stars_desc'
end end
# TODO: currently not implemented AFAIK
def sort_value_most_stars_asc
'stars_asc'
end
def sort_value_oldest_last_activity def sort_value_oldest_last_activity
'last_activity_on_asc' 'last_activity_on_asc'
end end
......
- is_explore = local_assigns.fetch(:is_explore, false)
- is_explore_trending = local_assigns.fetch(:is_explore_trending, false)
- without_tabs = local_assigns.fetch(:without_tabs, false)
= content_for :flash_message do = content_for :flash_message do
= render 'shared/project_limit' = render 'shared/project_limit'
...@@ -6,27 +9,27 @@ ...@@ -6,27 +9,27 @@
- if current_user.can_create_project? - if current_user.can_create_project?
.page-title-controls .page-title-controls
= link_to "New project", new_project_path, class: "btn btn-success" = link_to _("New project"), new_project_path, class: "btn btn-success"
.top-area.scrolling-tabs-container.inner-page-scroll-tabs .top-area.scrolling-tabs-container.inner-page-scroll-tabs
.fade-left= icon('angle-left') .fade-left= icon('angle-left')
.fade-right= icon('angle-right') .fade-right= icon('angle-right')
%ul.nav-links.scrolling-tabs.mobile-separator.nav.nav-tabs %ul.nav-links.scrolling-tabs.mobile-separator.nav.nav-tabs.border-0
= nav_link(page: [dashboard_projects_path, root_path]) do = nav_link(page: [dashboard_projects_path, root_path]) do
= link_to dashboard_projects_path, class: 'shortcuts-activity', data: {placement: 'right'} do = link_to dashboard_projects_path, class: 'shortcuts-activity', data: {placement: 'right'} do
Your projects = _("Your projects")
%span.badge.badge-pill= limited_counter_with_delimiter(@total_user_projects_count) %span.badge.badge-pill= limited_counter_with_delimiter(@total_user_projects_count)
= nav_link(page: starred_dashboard_projects_path) do = nav_link(page: starred_dashboard_projects_path) do
= link_to starred_dashboard_projects_path, data: {placement: 'right'} do = link_to starred_dashboard_projects_path, data: {placement: 'right'} do
Starred projects = _("Starred projects")
%span.badge.badge-pill= limited_counter_with_delimiter(@total_starred_projects_count) %span.badge.badge-pill= limited_counter_with_delimiter(@total_starred_projects_count)
= nav_link(page: [explore_root_path, trending_explore_projects_path, starred_explore_projects_path, explore_projects_path]) do = nav_link(page: [explore_root_path, trending_explore_projects_path, starred_explore_projects_path, explore_projects_path]) do
= link_to explore_root_path, data: {placement: 'right'} do = link_to explore_root_path, data: {placement: 'right'} do
Explore projects = _("Explore projects")
- unless Feature.enabled?(:project_list_filter_bar) - unless Feature.enabled?(:project_list_filter_bar)
.nav-controls .nav-controls
= render 'shared/projects/search_form' = render 'shared/projects/search_form'
= render 'shared/projects/dropdown' = render 'shared/projects/dropdown'
- if Feature.enabled?(:project_list_filter_bar) - if Feature.enabled?(:project_list_filter_bar)
.project-filters .project-filters
= render 'shared/projects/search_bar' = render 'shared/projects/search_bar', is_explore: is_explore, is_explore_trending: is_explore_trending, without_tabs: without_tabs
- is_explore = local_assigns.fetch(:is_explore, false)
- inactive_class = 'btn p-2'
- active_class = 'btn p-2 active'
- is_explore_trending = local_assigns.fetch(:is_explore_trending, false)
.nav-block .nav-block
- if !Feature.enabled?(:project_list_filter_bar) - if !Feature.enabled?(:project_list_filter_bar)
%ul.nav-links.mobile-separator.nav.nav-tabs %ul.nav-links.mobile-separator.nav.nav-tabs
...@@ -6,8 +11,11 @@ ...@@ -6,8 +11,11 @@
= nav_link(html_options: { class: ("active" if params[:personal].present?) }) do = nav_link(html_options: { class: ("active" if params[:personal].present?) }) do
= link_to s_('DashboardProjects|Personal'), filter_projects_path(personal: true) = link_to s_('DashboardProjects|Personal'), filter_projects_path(personal: true)
- else - else
%ul.btn-group.button-filter-group.d-flex.m-0.p-0 -# %ul.btn-group.button-filter-group.d-flex.m-0.p-0
= nav_link(html_options: { class: params[:personal].present? ? "btn p-2" : "btn p-2 active" }) do %div.btn-group.button-filter-group.d-flex.m-0.p-0
= link_to s_('DashboardProjects|All'), dashboard_projects_path - if is_explore
= nav_link(html_options: { class: params[:personal].present? ? "btn p-2 active" : "btn p-2" }) do = link_to s_('DashboardProjects|Trending'), trending_explore_projects_path, class: is_explore_trending ? active_class : inactive_class
= link_to s_('DashboardProjects|Personal'), filter_projects_path(personal: true) = link_to s_('DashboardProjects|All'), explore_projects_path, class: is_explore_trending ? inactive_class : active_class
- else
= link_to s_('DashboardProjects|All'), dashboard_projects_path, class: params[:personal].present? ? inactive_class : active_class
= link_to s_('DashboardProjects|Personal'), filter_projects_path(personal: true), class: params[:personal].present? ? active_class : inactive_class
...@@ -3,12 +3,13 @@ ...@@ -3,12 +3,13 @@
- breadcrumb_title _("Projects") - breadcrumb_title _("Projects")
- page_title _("Starred Projects") - page_title _("Starred Projects")
- header_title _("Projects"), dashboard_projects_path - header_title _("Projects"), dashboard_projects_path
- without_tabs = true
= render_dashboard_gold_trial(current_user) = render_dashboard_gold_trial(current_user)
%div{ class: container_class } %div{ class: container_class }
= render "projects/last_push" = render "projects/last_push"
= render 'dashboard/projects_head' = render 'dashboard/projects_head', without_tabs: without_tabs
- if params[:filter_projects] || any_projects?(@projects) - if params[:filter_projects] || any_projects?(@projects)
= render 'projects' = render 'projects'
......
...@@ -5,9 +5,10 @@ ...@@ -5,9 +5,10 @@
= render_dashboard_gold_trial(current_user) = render_dashboard_gold_trial(current_user)
- if current_user - if current_user
= render 'dashboard/projects_head' = render 'dashboard/projects_head', is_explore: true
- else - else
= render 'explore/head' = render 'explore/head'
= render 'explore/projects/nav' - unless Feature.enabled?(:project_list_filter_bar)
= render 'explore/projects/nav'
= render 'projects', projects: @projects = render 'projects', projects: @projects
...@@ -5,9 +5,10 @@ ...@@ -5,9 +5,10 @@
= render_dashboard_gold_trial(current_user) = render_dashboard_gold_trial(current_user)
- if current_user - if current_user
= render 'dashboard/projects_head' = render 'dashboard/projects_head', is_explore: true
- else - else
= render 'explore/head' = render 'explore/head'
= render 'explore/projects/nav' - unless Feature.enabled?(:project_list_filter_bar)
= render 'explore/projects/nav'
= render 'projects', projects: @projects = render 'projects', projects: @projects
...@@ -5,9 +5,10 @@ ...@@ -5,9 +5,10 @@
= render_dashboard_gold_trial(current_user) = render_dashboard_gold_trial(current_user)
- if current_user - if current_user
= render 'dashboard/projects_head' = render 'dashboard/projects_head', is_explore: true, is_explore_trending: true
- else - else
= render 'explore/head' = render 'explore/head'
= render 'explore/projects/nav' - unless Feature.enabled?(:project_list_filter_bar)
= render 'explore/projects/nav'
= render 'projects', projects: @projects = render 'projects', projects: @projects
- @sort ||= sort_value_latest_activity - @sort ||= sort_value_latest_activity
.dropdown.js-project-filter-dropdown-wrap .btn-group{ role: "group" }
- toggle_text = projects_sort_options_hash[@sort] .btn-group.dropdown.js-project-filter-dropdown-wrap.filter-with-icon{ role: "group" }
= dropdown_toggle(toggle_text, { toggle: 'dropdown', display: 'static' }, { id: 'sort-projects-dropdown' }) - toggle_text = projects_sort_option_titles[@sort]
%ul.dropdown-menu.dropdown-menu-right.dropdown-menu-selectable %button.dropdown-menu-toggle{ id: 'sort-projects-dropdown', type: 'button', data: { toggle: 'dropdown', display: 'static' }, class: 'btn btn-default' }
%li.dropdown-header = toggle_text
Sort by = icon('chevron-down')
- projects_sort_options_hash.each do |value, title| %ul.dropdown-menu.dropdown-menu-right.dropdown-menu-selectable
%li %li.dropdown-header
= link_to filter_projects_path(sort: value), class: ("is-active" if @sort == value) do Sort by
= title - projects_sort_options_hash.each do |value, title|
%li
= link_to filter_projects_path(sort: value), class: ("is-active" if projects_sort_option_titles[@sort] == title) do
= title
%li.divider
%li
= link_to filter_projects_path(archived: nil), class: ("is-active" unless params[:archived].present?) do
Hide archived projects
%li
= link_to filter_projects_path(archived: true), class: ("is-active" if Gitlab::Utils.to_boolean(params[:archived])) do
Show archived projects
%li
= link_to filter_projects_path(archived: 'only'), class: ("is-active" if params[:archived] == 'only') do
Show archived projects only
- if current_user
%li.divider %li.divider
%li %li
= link_to filter_projects_path(personal: nil), class: ("is-active" unless params[:personal].present?) do = link_to filter_projects_path(archived: nil), class: ("is-active" unless params[:archived].present?) do
Owned by anyone Hide archived projects
%li
= link_to filter_projects_path(archived: true), class: ("is-active" if Gitlab::Utils.to_boolean(params[:archived])) do
Show archived projects
%li %li
= link_to filter_projects_path(personal: true), class: ("is-active" if params[:personal].present?) do = link_to filter_projects_path(archived: 'only'), class: ("is-active" if params[:archived] == 'only') do
Owned by me Show archived projects only
- if @group && @group.shared_projects.present? - if current_user
%li.divider %li.divider
%li %li
= link_to filter_projects_path(shared: nil), class: ("is-active" unless params[:shared].present?) do = link_to filter_projects_path(personal: nil), class: ("is-active" unless params[:personal].present?) do
All projects Owned by anyone
%li %li
= link_to filter_projects_path(shared: 0), class: ("is-active" if params[:shared] == '0') do = link_to filter_projects_path(personal: true), class: ("is-active" if params[:personal].present?) do
Hide shared projects Owned by me
%li - if @group && @group.shared_projects.present?
= link_to filter_projects_path(shared: 1), class: ("is-active" if params[:shared] == '1') do %li.divider
Hide group projects %li
= link_to filter_projects_path(shared: nil), class: ("is-active" unless params[:shared].present?) do
All projects
%li
= link_to filter_projects_path(shared: 0), class: ("is-active" if params[:shared] == '0') do
Hide shared projects
%li
= link_to filter_projects_path(shared: 1), class: ("is-active" if params[:shared] == '1') do
Hide group projects
= project_sort_direction_button(@sort)
- @sort ||= sort_value_latest_activity - @sort ||= sort_value_latest_activity
-# TODO: simplify multiple utility classes into single class? - is_explore = local_assigns.fetch(:is_explore, false)
- is_explore_trending = local_assigns.fetch(:is_explore_trending, false)
- without_tabs = local_assigns.fetch(:without_tabs, false)
.filtered-search-block.row-content-block .filtered-search-block.row-content-block
.filtered-search-wrapper.d-flex.flex-column.flex-md-row.mt-2.mt-md-0 .filtered-search-wrapper.d-flex.mt-2.mt-lg-0
.d-inline.d-md-flex.mb-2.mb-md-0 - unless without_tabs
= render 'dashboard/projects/nav' .filtered-search-nav
.filtered-search-box.mb-2.mb-md-0.ml-md-2 = render 'dashboard/projects/nav', is_explore: is_explore, is_explore_trending: is_explore_trending
.filtered-search-box-input-container.pl-2 .filtered-search.field-with-icon
= render 'shared/projects/search_form', admin_view: false, search_form_placeholder: _("Search projects...") .btn-group{ role: "group" }
-# TODO: double check if theres a point to this button, or is it just aesthetic for now .btn-group{ role: "group" }
-# TODO: fix right hand border .filtered-search-box{ class: without_tabs ? "extended-filtered-search-box" : "" }
%button.input-group-append.btn.btn-secondary{ type: 'submit' } .filtered-search-box-input-container.pl-2
= sprite_icon('search', size: 18, css_class: 'search-icon ') = render 'shared/projects/search_form', admin_view: false, search_form_placeholder: _("Search projects...")
-# TODO: need to double check visibility is applying correctly -# TODO: since we are no longer triggering search when we type
.d-inline.d-md-flex.mb-2.mb-md-0.ml-md-2.flex-row -# we might be able to remove the `js-projects-list-filter`
.d-flex.align-items-center.px-2.font-weight-bold %button.btn.btn-secondary{ type: 'submit', form: 'project-filter-form' }
= sprite_icon('search', size: 16, css_class: 'search-icon ')
.filtered-search-dropdown
.filtered-search-dropdown-label
%span %span
= _("Visibility") = _("Visibility")
.dropdown.js-project-filter-dropdown-wrap.inline-md .dropdown.js-project-filter-dropdown-wrap.inline-md
= render 'explore/projects/filter', has_label: true = render 'explore/projects/filter', has_label: true
.d-inline.d-md-flex.mb-2.mb-md-0.ml-md-2.flex-row .filtered-search-dropdown
.d-flex.align-items-center.px-2.font-weight-bold .filtered-search-dropdown-label
%span %span
= _("Sort by") = _("Sort by")
= render 'shared/projects/dropdown' = render 'shared/projects/dropdown'
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
= form_tag filter_projects_path, method: :get, class: 'project-filter-form', id: 'project-filter-form' do |f| = form_tag filter_projects_path, method: :get, class: 'project-filter-form', id: 'project-filter-form' do |f|
= search_field_tag :name, params[:name], = search_field_tag :name, params[:name],
placeholder: placeholder, placeholder: placeholder,
class: "project-filter-form-field form-control js-projects-list-filter #{form_field_classes}", class: "project-filter-form-field form-control #{form_field_classes}",
spellcheck: false, spellcheck: false,
id: 'project-filter-form-field', id: 'project-filter-form-field',
tabindex: "2", tabindex: "2",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment