Commit dbced090 authored by Fatih Acet's avatar Fatih Acet Committed by Kushal Pandya
Browse files

Make flash notifications sticky

This commit also unifies layout structure
and remove no_container flag
parent b7c809d3edcf
import _ from 'underscore';
import { spriteIcon } from './lib/utils/common_utils';
const hideFlash = (flashEl, fadeTransition = true) => {
if (fadeTransition) {
......@@ -35,16 +36,11 @@ const createAction = config => `
</a>
`;
const createFlashEl = (message, type, isFixedLayout = false) => `
<div
class="flash-${type}"
>
<div
class="flash-text ${
isFixedLayout ? 'container-fluid container-limited limit-container-width' : ''
}"
>
const createFlashEl = (message, type) => `
<div class="flash-content flash-${type} rounded">
<div class="flash-text">
${_.escape(message)}
${spriteIcon('close', 'close-icon')}
</div>
</div>
`;
......@@ -76,15 +72,10 @@ const createFlash = function createFlash(
addBodyClass = false,
) {
const flashContainer = parent.querySelector('.flash-container');
const navigation = parent.querySelector('.content');
if (!flashContainer) return null;
const isFixedLayout = navigation
? navigation.parentNode.classList.contains('container-limited')
: true;
flashContainer.innerHTML = createFlashEl(message, type, isFixedLayout);
flashContainer.innerHTML = createFlashEl(message, type);
const flashEl = flashContainer.querySelector(`.flash-${type}`);
removeFlashClickListener(flashEl, fadeTransition);
......
......@@ -5,9 +5,10 @@ import { parseBoolean } from '~/lib/utils/common_utils';
document.addEventListener('DOMContentLoaded', () => {
const twoFactorNode = document.querySelector('.js-two-factor-auth');
const skippable = parseBoolean(twoFactorNode.dataset.twoFactorSkippable);
if (skippable) {
const button = `<a class="btn btn-sm btn-warning float-right" data-method="patch" href="${twoFactorNode.dataset.two_factor_skip_url}">Configure it later</a>`;
const flashAlert = document.querySelector('.flash-alert .container-fluid');
const flashAlert = document.querySelector('.flash-alert');
if (flashAlert) flashAlert.insertAdjacentHTML('beforeend', button);
}
......
$notification-box-shadow-color: rgba(0, 0, 0, 0.25);
.flash-container {
cursor: pointer;
margin: 0;
......@@ -6,12 +8,32 @@
position: relative;
z-index: 1;
&.sticky {
position: sticky;
position: -webkit-sticky;
top: $flash-container-top;
z-index: 200;
.flash-content {
box-shadow: 0 2px 4px 0 $notification-box-shadow-color;
}
}
.close-icon {
width: 16px;
height: 16px;
position: absolute;
right: $gl-padding;
top: $gl-padding;
}
.flash-notice,
.flash-alert,
.flash-success,
.flash-warning {
border-radius: $border-radius-default;
color: $white-light;
padding-right: $gl-padding * 2;
.container-fluid,
.container-fluid.container-limited {
......@@ -97,3 +119,28 @@
}
}
}
.gl-browser-ie .flash-container {
position: fixed;
max-width: $limited-layout-width;
left: 50%;
.flash-alert {
position: relative;
left: -50%;
}
}
.with-system-header .flash-container {
top: $flash-container-top + $system-header-height;
}
.with-performance-bar {
.flash-container {
top: $flash-container-top + $performance-bar-height;
}
&.with-system-header .flash-container {
top: $flash-container-top + $performance-bar-height + $system-header-height;
}
}
......@@ -29,6 +29,15 @@ body {
}
}
.container-fluid {
&.limit-container-width {
.flash-container.sticky {
max-width: $limited-layout-width;
margin: 0 auto;
}
}
}
.content-wrapper {
margin-top: $header-height;
padding-bottom: 100px;
......
......@@ -377,6 +377,7 @@ $performance-bar-height: 35px;
$system-header-height: 16px;
$system-footer-height: $system-header-height;
$flash-height: 52px;
$flash-container-top: 48px;
$context-header-height: 60px;
$breadcrumb-min-height: 48px;
$home-panel-title-row-height: 64px;
......
- @no_container = true
- page_title "Background Jobs"
%div{ class: container_class }
%h3.page-title Background Jobs
%p.light GitLab uses #{link_to "sidekiq", "http://sidekiq.org/"} library for async job processing
%h3.page-title Background Jobs
%p.light GitLab uses #{link_to "sidekiq", "http://sidekiq.org/"} library for async job processing
%hr
.card
%iframe{ src: sidekiq_path, width: '100%', height: 970, style: "border: 0" }
%hr
.card
%iframe{ src: sidekiq_path, width: '100%', height: 970, style: "border: 0" }
- @no_container = true
- breadcrumb_title "Dashboard"
%div{ class: container_class }
= render_if_exists 'admin/licenses/breakdown', license: @license
= render_if_exists 'admin/licenses/breakdown', license: @license
.admin-dashboard.prepend-top-default
.row
.col-sm-4
.info-well.dark-well
.well-segment.well-centered
= link_to admin_projects_path do
%h3.text-center
Projects:
= approximate_count_with_delimiters(@counts, Project)
%hr
= link_to('New project', new_project_path, class: "btn btn-success")
.col-sm-4
.info-well.dark-well
.well-segment.well-centered
= link_to admin_users_path do
%h3.text-center
Users:
= approximate_count_with_delimiters(@counts, User)
%hr
.btn-group.d-flex{ role: 'group' }
= link_to 'New user', new_admin_user_path, class: "btn btn-success"
= render_if_exists 'admin/dashboard/users_statistics'
.col-sm-4
.info-well.dark-well
.well-segment.well-centered
= link_to admin_groups_path do
%h3.text-center
Groups:
= approximate_count_with_delimiters(@counts, Group)
%hr
= link_to 'New group', new_admin_group_path, class: "btn btn-success"
.row
.col-md-4
.info-well
.well-segment.admin-well.admin-well-statistics
%h4 Statistics
%p
Forks
%span.light.float-right
= approximate_fork_count_with_delimiters(@counts)
%p
Issues
%span.light.float-right
= approximate_count_with_delimiters(@counts, Issue)
%p
Merge Requests
%span.light.float-right
= approximate_count_with_delimiters(@counts, MergeRequest)
%p
Notes
%span.light.float-right
= approximate_count_with_delimiters(@counts, Note)
%p
Snippets
%span.light.float-right
= approximate_count_with_delimiters(@counts, Snippet)
%p
SSH Keys
%span.light.float-right
= approximate_count_with_delimiters(@counts, Key)
%p
Milestones
%span.light.float-right
= approximate_count_with_delimiters(@counts, Milestone)
%p
Active Users
%span.light.float-right
= number_with_delimiter(User.active.count)
.col-md-4
.info-well
.well-segment.admin-well.admin-well-features
%h4 Features
= feature_entry(_('Sign up'), href: admin_application_settings_path(anchor: 'js-signup-settings'))
= feature_entry(_('LDAP'), enabled: Gitlab.config.ldap.enabled)
= feature_entry(_('Gravatar'), href: admin_application_settings_path(anchor: 'js-account-settings'), enabled: gravatar_enabled?)
= feature_entry(_('OmniAuth'), href: admin_application_settings_path(anchor: 'js-signin-settings'), enabled: Gitlab::Auth.omniauth_enabled?)
= feature_entry(_('Reply by email'), enabled: Gitlab::IncomingEmail.enabled?)
.admin-dashboard.prepend-top-default
.row
.col-sm-4
.info-well.dark-well
.well-segment.well-centered
= link_to admin_projects_path do
%h3.text-center
Projects:
= approximate_count_with_delimiters(@counts, Project)
%hr
= link_to('New project', new_project_path, class: "btn btn-success")
.col-sm-4
.info-well.dark-well
.well-segment.well-centered
= link_to admin_users_path do
%h3.text-center
Users:
= approximate_count_with_delimiters(@counts, User)
%hr
.btn-group.d-flex{ role: 'group' }
= link_to 'New user', new_admin_user_path, class: "btn btn-success"
= render_if_exists 'admin/dashboard/users_statistics'
.col-sm-4
.info-well.dark-well
.well-segment.well-centered
= link_to admin_groups_path do
%h3.text-center
Groups:
= approximate_count_with_delimiters(@counts, Group)
%hr
= link_to 'New group', new_admin_group_path, class: "btn btn-success"
.row
.col-md-4
.info-well
.well-segment.admin-well.admin-well-statistics
%h4 Statistics
%p
Forks
%span.light.float-right
= approximate_fork_count_with_delimiters(@counts)
%p
Issues
%span.light.float-right
= approximate_count_with_delimiters(@counts, Issue)
%p
Merge Requests
%span.light.float-right
= approximate_count_with_delimiters(@counts, MergeRequest)
%p
Notes
%span.light.float-right
= approximate_count_with_delimiters(@counts, Note)
%p
Snippets
%span.light.float-right
= approximate_count_with_delimiters(@counts, Snippet)
%p
SSH Keys
%span.light.float-right
= approximate_count_with_delimiters(@counts, Key)
%p
Milestones
%span.light.float-right
= approximate_count_with_delimiters(@counts, Milestone)
%p
Active Users
%span.light.float-right
= number_with_delimiter(User.active.count)
.col-md-4
.info-well
.well-segment.admin-well.admin-well-features
%h4 Features
= feature_entry(_('Sign up'), href: admin_application_settings_path(anchor: 'js-signup-settings'))
= feature_entry(_('LDAP'), enabled: Gitlab.config.ldap.enabled)
= feature_entry(_('Gravatar'), href: admin_application_settings_path(anchor: 'js-account-settings'), enabled: gravatar_enabled?)
= feature_entry(_('OmniAuth'), href: admin_application_settings_path(anchor: 'js-signin-settings'), enabled: Gitlab::Auth.omniauth_enabled?)
= feature_entry(_('Reply by email'), enabled: Gitlab::IncomingEmail.enabled?)
= render_if_exists 'admin/dashboard/elastic_and_geo'
= render_if_exists 'admin/dashboard/elastic_and_geo'
= feature_entry(_('Container Registry'), href: ci_cd_admin_application_settings_path(anchor: 'js-registry-settings'), enabled: Gitlab.config.registry.enabled)
= feature_entry(_('Gitlab Pages'), href: help_instance_configuration_url, enabled: Gitlab.config.pages.enabled)
= feature_entry(_('Shared Runners'), href: admin_runners_path, enabled: Gitlab.config.gitlab_ci.shared_runners_enabled)
.col-md-4
.info-well
.well-segment.admin-well
%h4
Components
- if Gitlab::CurrentSettings.version_check_enabled
.float-right
= version_status_badge
%p
%a{ href: admin_application_settings_path }
GitLab
= feature_entry(_('Container Registry'), href: ci_cd_admin_application_settings_path(anchor: 'js-registry-settings'), enabled: Gitlab.config.registry.enabled)
= feature_entry(_('Gitlab Pages'), href: help_instance_configuration_url, enabled: Gitlab.config.pages.enabled)
= feature_entry(_('Shared Runners'), href: admin_runners_path, enabled: Gitlab.config.gitlab_ci.shared_runners_enabled)
.col-md-4
.info-well
.well-segment.admin-well
%h4
Components
- if Gitlab::CurrentSettings.version_check_enabled
.float-right
= version_status_badge
%p
%a{ href: admin_application_settings_path }
GitLab
%span.float-right
= Gitlab::VERSION
= "(#{Gitlab.revision})"
%p
GitLab Shell
%span.float-right
= Gitlab::Shell.new.version
%p
GitLab Workhorse
%span.float-right
= gitlab_workhorse_version
%p
GitLab API
%span.float-right
= API::API::version
- if Gitlab.config.pages.enabled
%p
GitLab Pages
%span.float-right
= Gitlab::VERSION
= "(#{Gitlab.revision})"
%p
GitLab Shell
%span.float-right
= Gitlab::Shell.new.version
%p
GitLab Workhorse
%span.float-right
= gitlab_workhorse_version
%p
GitLab API
%span.float-right
= API::API::version
- if Gitlab.config.pages.enabled
%p
GitLab Pages
%span.float-right
= Gitlab::Pages::VERSION
= Gitlab::Pages::VERSION
= render_if_exists 'admin/dashboard/geo'
= render_if_exists 'admin/dashboard/geo'
%p
Ruby
%span.float-right
#{RUBY_VERSION}p#{RUBY_PATCHLEVEL}
%p
Rails
%span.float-right
#{Rails::VERSION::STRING}
%p
= Gitlab::Database.human_adapter_name
%span.float-right
= Gitlab::Database.version
%p
= link_to "Gitaly Servers", admin_gitaly_servers_path
.row
.col-md-4
.info-well
.well-segment.admin-well
%h4 Latest projects
- @projects.each do |project|
%p
= link_to project.full_name, admin_project_path(project), class: 'str-truncated-60'
%span.light.float-right
#{time_ago_with_tooltip(project.created_at)}
.col-md-4
.info-well
.well-segment.admin-well
%h4 Latest users
- @users.each do |user|
%p
= link_to [:admin, user], class: 'str-truncated-60' do
= user.name
%span.light.float-right
#{time_ago_with_tooltip(user.created_at)}
.col-md-4
.info-well
.well-segment.admin-well
%h4 Latest groups
- @groups.each do |group|
%p
= link_to [:admin, group], class: 'str-truncated-60' do
= group.full_name
%span.light.float-right
#{time_ago_with_tooltip(group.created_at)}
%p
Ruby
%span.float-right
#{RUBY_VERSION}p#{RUBY_PATCHLEVEL}
%p
Rails
%span.float-right
#{Rails::VERSION::STRING}
%p
= Gitlab::Database.human_adapter_name
%span.float-right
= Gitlab::Database.version
%p
= link_to "Gitaly Servers", admin_gitaly_servers_path
.row
.col-md-4
.info-well
.well-segment.admin-well
%h4 Latest projects
- @projects.each do |project|
%p
= link_to project.full_name, admin_project_path(project), class: 'str-truncated-60'
%span.light.float-right
#{time_ago_with_tooltip(project.created_at)}
.col-md-4
.info-well
.well-segment.admin-well
%h4 Latest users
- @users.each do |user|
%p
= link_to [:admin, user], class: 'str-truncated-60' do
= user.name
%span.light.float-right
#{time_ago_with_tooltip(user.created_at)}
.col-md-4
.info-well
.well-segment.admin-well
%h4 Latest groups
- @groups.each do |group|
%p
= link_to [:admin, group], class: 'str-truncated-60' do
= group.full_name
%span.light.float-right
#{time_ago_with_tooltip(group.created_at)}
- @no_container = true
- page_title _("Groups")
%div{ class: container_class }
.top-area
.prepend-top-default.append-bottom-default
= form_tag admin_groups_path, method: :get, class: 'js-search-form' do |f|
= hidden_field_tag :sort, @sort
.search-holder
- project_name = params[:name].present? ? params[:name] : nil
.search-field-holder
= search_field_tag :name, project_name, class: "form-control search-text-input js-search-input", autofocus: true, spellcheck: false, placeholder: 'Search by name'
= icon("search", class: "search-icon")
= render "shared/groups/dropdown", options_hash: admin_groups_sort_options_hash
= link_to new_admin_group_path, class: "btn btn-success" do
= _('New group')
%ul.content-list
= render @groups
.top-area
.prepend-top-default.append-bottom-default
= form_tag admin_groups_path, method: :get, class: 'js-search-form' do |f|
= hidden_field_tag :sort, @sort
.search-holder
- project_name = params[:name].present? ? params[:name] : nil
.search-field-holder
= search_field_tag :name, project_name, class: "form-control search-text-input js-search-input", autofocus: true, spellcheck: false, placeholder: 'Search by name'
= icon("search", class: "search-icon")
= render "shared/groups/dropdown", options_hash: admin_groups_sort_options_hash
= link_to new_admin_group_path, class: "btn btn-success" do
= _('New group')
%ul.content-list
= render @groups
= paginate @groups, theme: "gitlab"
= paginate @groups, theme: "gitlab"
- @no_container = true
- page_title _('Health Check')
- no_errors = @errors.blank?
%div{ class: container_class }
%h3.page-title= page_title
.bs-callout.clearfix
.float-left
%p
#{ s_('HealthCheck|Access token is') }
%code#health-check-token= Gitlab::CurrentSettings.health_check_access_token
.prepend-top-10
= button_to _("Reset health check access token"), reset_health_check_token_admin_application_settings_path,
method: :put, class: 'btn btn-default',
data: { confirm: _('Are you sure you want to reset the health check token?') }
%p.light
#{ _('Health information can be retrieved from the following endpoints. More information is available') }
= link_to s_('More information is available|here'), help_page_path('user/admin_area/monitoring/health_check')
%ul
%li
%code= readiness_url(token: Gitlab::CurrentSettings.health_check_access_token)
%li
%code= liveness_url(token: Gitlab::CurrentSettings.health_check_access_token)
%li
%code= metrics_url(token: Gitlab::CurrentSettings.health_check_access_token)
= render_if_exists 'admin/health_check/health_check_url'
%hr
.card
.card-header
Current Status:
- if no_errors
= icon('circle', class: 'cgreen')
#{ s_('HealthCheck|Healthy') }
- else
= icon('warning', class: 'cred')
#{ s_('HealthCheck|Unhealthy') }
.card-body
- if no_errors
#{ s_('HealthCheck|No Health Problems Detected') }
- else
= @errors
%h3.page-title= page_title
.bs-callout.clearfix
.float-left
%p
#{ s_('HealthCheck|Access token is') }
%code#health-check-token= Gitlab::CurrentSettings.health_check_access_token
.prepend-top-10
= button_to _("Reset health check access token"), reset_health_check_token_admin_application_settings_path,
method: :put, class: 'btn btn-default',
data: { confirm: _('Are you sure you want to reset the health check token?') }
%p.light
#{ _('Health information can be retrieved from the following endpoints. More information is available') }
= link_to s_('More information is available|here'), help_page_path('user/admin_area/monitoring/health_check')
%ul
%li
%code= readiness_url(token: Gitlab::CurrentSettings.health_check_access_token)
%li
%code= liveness_url(token: Gitlab::CurrentSettings.health_check_access_token)
%li
%code= metrics_url(token: Gitlab::CurrentSettings.health_check_access_token)
= render_if_exists 'admin/health_check/health_check_url'
%hr
.card
.card-header
Current Status:
- if no_errors
= icon('circle', class: 'cgreen')
#{ s_('HealthCheck|Healthy') }