diff options
Diffstat (limited to 'app')
| -rw-r--r-- | app/assets/javascripts/fly_out_nav.js | 1 | ||||
| -rw-r--r-- | app/assets/javascripts/new_sidebar.js | 40 | ||||
| -rw-r--r-- | app/assets/stylesheets/new_sidebar.scss | 104 | ||||
| -rw-r--r-- | app/models/project_wiki.rb | 4 | ||||
| -rw-r--r-- | app/models/wiki_page.rb | 78 | ||||
| -rw-r--r-- | app/services/wiki_pages/update_service.rb | 2 | ||||
| -rw-r--r-- | app/views/layouts/nav/_new_admin_sidebar.html.haml | 2 | ||||
| -rw-r--r-- | app/views/layouts/nav/_new_group_sidebar.html.haml | 2 | ||||
| -rw-r--r-- | app/views/layouts/nav/_new_profile_sidebar.html.haml | 2 | ||||
| -rw-r--r-- | app/views/layouts/nav/_new_project_sidebar.html.haml | 2 | ||||
| -rw-r--r-- | app/views/projects/wikis/_form.html.haml | 5 | ||||
| -rw-r--r-- | app/views/shared/_sidebar_toggle_button.html.haml | 4 |
12 files changed, 205 insertions, 41 deletions
diff --git a/app/assets/javascripts/fly_out_nav.js b/app/assets/javascripts/fly_out_nav.js index 8e9a97fe207..301e82f4610 100644 --- a/app/assets/javascripts/fly_out_nav.js +++ b/app/assets/javascripts/fly_out_nav.js @@ -23,6 +23,7 @@ export const showSubLevelItems = (el) => { const top = calculateTop(boundingRect, subItems.offsetHeight); const isAbove = top < boundingRect.top; + subItems.classList.add('fly-out-list'); subItems.style.transform = `translate3d(0, ${Math.floor(top)}px, 0)`; if (isAbove) { diff --git a/app/assets/javascripts/new_sidebar.js b/app/assets/javascripts/new_sidebar.js index 5f98aff8ced..3a3e6b14ec4 100644 --- a/app/assets/javascripts/new_sidebar.js +++ b/app/assets/javascripts/new_sidebar.js @@ -1,23 +1,63 @@ +import Cookies from 'js-cookie'; +import _ from 'underscore'; +/* global bp */ +import './breakpoints'; + export default class NewNavSidebar { constructor() { this.initDomElements(); + this.render(); } initDomElements() { + this.$page = $('.page-with-sidebar'); this.$sidebar = $('.nav-sidebar'); this.$overlay = $('.mobile-overlay'); this.$openSidebar = $('.toggle-mobile-nav'); this.$closeSidebar = $('.close-nav-button'); + this.$sidebarToggle = $('.js-toggle-sidebar'); } bindEvents() { this.$openSidebar.on('click', () => this.toggleSidebarNav(true)); this.$closeSidebar.on('click', () => this.toggleSidebarNav(false)); this.$overlay.on('click', () => this.toggleSidebarNav(false)); + this.$sidebarToggle.on('click', () => { + const value = !this.$sidebar.hasClass('sidebar-icons-only'); + this.toggleCollapsedSidebar(value); + }); + + $(window).on('resize', () => _.debounce(this.render(), 100)); + } + + static setCollapsedCookie(value) { + if (bp.getBreakpointSize() !== 'lg') { + return; + } + Cookies.set('sidebar_collapsed', value, { expires: 365 * 10 }); } toggleSidebarNav(show) { this.$sidebar.toggleClass('nav-sidebar-expanded', show); this.$overlay.toggleClass('mobile-nav-open', show); + this.$sidebar.removeClass('sidebar-icons-only'); + } + + toggleCollapsedSidebar(collapsed) { + this.$sidebar.toggleClass('sidebar-icons-only', collapsed); + this.$page.toggleClass('page-with-new-sidebar', !collapsed); + this.$page.toggleClass('page-with-icon-sidebar', collapsed); + NewNavSidebar.setCollapsedCookie(collapsed); + } + + render() { + const breakpoint = bp.getBreakpointSize(); + + if (breakpoint === 'sm' || breakpoint === 'md') { + this.toggleCollapsedSidebar(true); + } else if (breakpoint === 'lg') { + const collapse = Cookies.get('sidebar_collapsed') === 'true'; + this.toggleCollapsedSidebar(collapse); + } } } diff --git a/app/assets/stylesheets/new_sidebar.scss b/app/assets/stylesheets/new_sidebar.scss index 6fd413dd7e3..10c9c97df0e 100644 --- a/app/assets/stylesheets/new_sidebar.scss +++ b/app/assets/stylesheets/new_sidebar.scss @@ -12,9 +12,12 @@ $hover-background: $white-light; $hover-color: $gl-text-color; $inactive-color: $gl-text-color-secondary; $new-sidebar-width: 220px; +$new-sidebar-collapsed-width: 50px; .page-with-new-sidebar { - @media (min-width: $screen-sm-min) { + padding-left: $new-sidebar-collapsed-width; + + @media (min-width: $screen-lg-min) { padding-left: $new-sidebar-width; } @@ -29,6 +32,12 @@ $new-sidebar-width: 220px; } } +.page-with-icon-sidebar { + @media (min-width: $screen-sm-min) { + padding-left: $new-sidebar-collapsed-width; + } +} + .context-header { position: relative; margin-right: 2px; @@ -114,6 +123,16 @@ $new-sidebar-width: 220px; background-color: $gray-normal; box-shadow: inset -2px 0 0 $border-color; + &.sidebar-icons-only { + width: $new-sidebar-collapsed-width; + + .nav-item-name, + .badge, + .project-title { + display: none; + } + } + &.nav-sidebar-expanded { left: 0; } @@ -208,6 +227,8 @@ $new-sidebar-width: 220px; } .sidebar-top-level-items { + margin-bottom: 60px; + > li { > a { @media (min-width: $screen-sm-min) { @@ -229,7 +250,7 @@ $new-sidebar-width: 220px; @media (min-width: $screen-sm-min) { position: fixed; top: 0; - left: 220px; + left: $new-sidebar-width; width: 150px; margin-top: -1px; padding: 8px 1px; @@ -315,6 +336,85 @@ $new-sidebar-width: 220px; } } + +// Collapsed nav + +.toggle-sidebar-button { + width: $new-sidebar-width - 2px; + position: fixed; + bottom: 0; + padding: 16px; + background-color: $gray-normal; + border-top: 2px solid $border-color; + color: $gl-text-color-secondary; + display: flex; + align-items: center; + + @media (max-width: $screen-xs-max) { + display: none; + } + + i { + font-size: 20px; + margin-right: 8px; + } + + .fa-angle-double-right { + display: none; + } + + &:hover { + background-color: $border-color; + color: $gl-text-color; + } +} + +.sidebar-icons-only { + .context-header { + height: 60px; + + a { + padding: 10px 4px; + } + } + + li a { + padding: 12px 15px; + } + + .sidebar-top-level-items > li { + &.active a { + padding-left: 12px; + } + + .sidebar-sub-level-items { + @media (min-width: $screen-sm-min) { + left: $new-sidebar-collapsed-width; + } + + &:not(.flyout-list) { + display: none; + } + } + } + + .toggle-sidebar-button { + width: $new-sidebar-collapsed-width - 2px; + + .collapse-text, + .fa-angle-double-left { + display: none; + } + + .fa-angle-double-right { + display: block; + } + } +} + + +// Mobile nav + .toggle-mobile-nav { display: none; background-color: transparent; diff --git a/app/models/project_wiki.rb b/app/models/project_wiki.rb index e8929a35836..698fdf7a20c 100644 --- a/app/models/project_wiki.rb +++ b/app/models/project_wiki.rb @@ -113,10 +113,10 @@ class ProjectWiki return false end - def update_page(page, content, format = :markdown, message = nil) + def update_page(page, content:, title: nil, format: :markdown, message: nil) commit = commit_details(:updated, message, page.title) - wiki.update_page(page, page.name, format.to_sym, content, commit) + wiki.update_page(page, title || page.name, format.to_sym, content, commit) update_project_activity end diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb index 148998bc9be..5c7c2204374 100644 --- a/app/models/wiki_page.rb +++ b/app/models/wiki_page.rb @@ -180,31 +180,50 @@ class WikiPage # # Returns the String SHA1 of the newly created page # or False if the save was unsuccessful. - def create(attr = {}) - @attributes.merge!(attr) + def create(attrs = {}) + @attributes.merge!(attrs) - save :create_page, title, content, format, message + save(page_details: title) do + wiki.create_page(title, content, format, message) + end end # Updates an existing Wiki Page, creating a new version. # - # new_content - The raw markup content to replace the existing. - # format - Optional symbol representing the content format. - # See ProjectWiki::MARKUPS Hash for available formats. - # message - Optional commit message to set on the new version. - # last_commit_sha - Optional last commit sha to validate the page unchanged. + # attrs - Hash of attributes to be updated on the page. + # :content - The raw markup content to replace the existing. + # :format - Optional symbol representing the content format. + # See ProjectWiki::MARKUPS Hash for available formats. + # :message - Optional commit message to set on the new version. + # :last_commit_sha - Optional last commit sha to validate the page unchanged. + # :title - The Title to replace existing title # # Returns the String SHA1 of the newly created page # or False if the save was unsuccessful. - def update(new_content, format: :markdown, message: nil, last_commit_sha: nil) - @attributes[:content] = new_content - @attributes[:format] = format - + def update(attrs = {}) + last_commit_sha = attrs.delete(:last_commit_sha) if last_commit_sha && last_commit_sha != self.last_commit_sha raise PageChangedError.new("You are attempting to update a page that has changed since you started editing it.") end - save :update_page, @page, content, format, message + attrs.slice!(:content, :format, :message, :title) + @attributes.merge!(attrs) + page_details = + if title.present? && @page.title != title + title + else + @page.url_path + end + + save(page_details: page_details) do + wiki.update_page( + @page, + content: content, + format: format, + message: attrs[:message], + title: title + ) + end end # Destroys the Wiki Page. @@ -236,30 +255,19 @@ class WikiPage attributes[:format] = @page.format end - def save(method, *args) - saved = false + def save(page_details:) + return unless valid? - project_wiki = wiki - if valid? && project_wiki.send(method, *args) - - page_details = if method == :update_page - # Use url_path instead of path to omit format extension - @page.url_path - else - title - end - - page_title, page_dir = project_wiki.page_title_and_dir(page_details) - gollum_wiki = project_wiki.wiki - @page = gollum_wiki.paged(page_title, page_dir) + unless yield + errors.add(:base, wiki.error_message) + return false + end - set_attributes + page_title, page_dir = wiki.page_title_and_dir(page_details) + gollum_wiki = wiki.wiki + @page = gollum_wiki.paged(page_title, page_dir) - @persisted = true - saved = true - else - errors.add(:base, project_wiki.error_message) if project_wiki.error_message - end - saved + set_attributes + @persisted = errors.blank? end end diff --git a/app/services/wiki_pages/update_service.rb b/app/services/wiki_pages/update_service.rb index c628e6781af..93cbd9a509f 100644 --- a/app/services/wiki_pages/update_service.rb +++ b/app/services/wiki_pages/update_service.rb @@ -1,7 +1,7 @@ module WikiPages class UpdateService < WikiPages::BaseService def execute(page) - if page.update(@params[:content], format: @params[:format], message: @params[:message], last_commit_sha: @params[:last_commit_sha]) + if page.update(@params) execute_hooks(page, 'update') end diff --git a/app/views/layouts/nav/_new_admin_sidebar.html.haml b/app/views/layouts/nav/_new_admin_sidebar.html.haml index 54ea39a2d36..06cfa509ebf 100644 --- a/app/views/layouts/nav/_new_admin_sidebar.html.haml +++ b/app/views/layouts/nav/_new_admin_sidebar.html.haml @@ -149,3 +149,5 @@ = custom_icon('settings') %span.nav-item-name Settings + + = render 'shared/sidebar_toggle_button' diff --git a/app/views/layouts/nav/_new_group_sidebar.html.haml b/app/views/layouts/nav/_new_group_sidebar.html.haml index 1fc92765c40..4a04b27b3d9 100644 --- a/app/views/layouts/nav/_new_group_sidebar.html.haml +++ b/app/views/layouts/nav/_new_group_sidebar.html.haml @@ -88,3 +88,5 @@ = link_to group_settings_ci_cd_path(@group), title: 'CI / CD' do %span CI / CD + + = render 'shared/sidebar_toggle_button' diff --git a/app/views/layouts/nav/_new_profile_sidebar.html.haml b/app/views/layouts/nav/_new_profile_sidebar.html.haml index f715d8a63f9..df869fef604 100644 --- a/app/views/layouts/nav/_new_profile_sidebar.html.haml +++ b/app/views/layouts/nav/_new_profile_sidebar.html.haml @@ -83,3 +83,5 @@ = custom_icon('authentication_log') %span.nav-item-name Authentication log + + = render 'shared/sidebar_toggle_button' diff --git a/app/views/layouts/nav/_new_project_sidebar.html.haml b/app/views/layouts/nav/_new_project_sidebar.html.haml index e8fde923134..4b7209fa69e 100644 --- a/app/views/layouts/nav/_new_project_sidebar.html.haml +++ b/app/views/layouts/nav/_new_project_sidebar.html.haml @@ -222,6 +222,8 @@ %span Members + = render 'shared/sidebar_toggle_button' + -# Shortcut to Project > Activity %li.hidden = link_to activity_project_path(@project), title: 'Activity', class: 'shortcuts-project-activity' do diff --git a/app/views/projects/wikis/_form.html.haml b/app/views/projects/wikis/_form.html.haml index adb8d5aaecb..e5a1fccf9ba 100644 --- a/app/views/projects/wikis/_form.html.haml +++ b/app/views/projects/wikis/_form.html.haml @@ -3,9 +3,12 @@ = form_for [@project.namespace.becomes(Namespace), @project, @page], method: @page.persisted? ? :put : :post, html: { class: 'form-horizontal wiki-form common-note-form prepend-top-default js-quick-submit' } do |f| = form_errors(@page) - = f.hidden_field :title, value: @page.title - if @page.persisted? = f.hidden_field :last_commit_sha, value: @page.last_commit_sha + + .form-group + .col-sm-12= f.label :title, class: 'control-label-full-width' + .col-sm-12= f.text_field :title, class: 'form-control', value: @page.title .form-group .col-sm-12= f.label :format, class: 'control-label-full-width' .col-sm-12 diff --git a/app/views/shared/_sidebar_toggle_button.html.haml b/app/views/shared/_sidebar_toggle_button.html.haml new file mode 100644 index 00000000000..e70faad4894 --- /dev/null +++ b/app/views/shared/_sidebar_toggle_button.html.haml @@ -0,0 +1,4 @@ +%a.toggle-sidebar-button.js-toggle-sidebar{ role: "button", type: "button", title: "Toggle sidebar" } + = icon('angle-double-left') + = icon('angle-double-right') + %span.collapse-text Collapse sidebar |
