Commit e31858b3 authored by GitLab Bot's avatar GitLab Bot
Browse files

Add latest changes from gitlab-org/gitlab@master

parent a838a86d2c9c
......@@ -8,6 +8,7 @@ import {
GlDropdownItem,
GlFormGroup,
GlModal,
GlSearchBoxByType,
GlModalDirective,
GlTooltipDirective,
} from '@gitlab/ui';
......@@ -15,6 +16,7 @@ import PanelType from 'ee_else_ce/monitoring/components/panel_type.vue';
import { s__ } from '~/locale';
import createFlash from '~/flash';
import Icon from '~/vue_shared/components/icon.vue';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { getParameterValues, mergeUrlParams, redirectTo } from '~/lib/utils/url_utility';
import invalidUrl from '~/lib/utils/invalid_url';
......@@ -38,6 +40,7 @@ export default {
GlButton,
GlDropdown,
GlDropdownItem,
GlSearchBoxByType,
GlFormGroup,
GlModal,
......@@ -52,6 +55,7 @@ export default {
GlTooltip: GlTooltipDirective,
TrackEvent: TrackEventDirective,
},
mixins: [glFeatureFlagsMixin()],
props: {
externalDashboardUrl: {
type: String,
......@@ -198,13 +202,12 @@ export default {
'dashboard',
'emptyState',
'showEmptyState',
'environments',
'deploymentData',
'useDashboardEndpoint',
'allDashboards',
'additionalPanelTypesEnabled',
]),
...mapGetters('monitoringDashboard', ['getMetricStates']),
...mapGetters('monitoringDashboard', ['getMetricStates', 'filteredEnvironments']),
firstDashboard() {
return this.environmentsEndpoint.length > 0 && this.allDashboards.length > 0
? this.allDashboards[0]
......@@ -227,6 +230,9 @@ export default {
this.externalDashboardUrl.length
);
},
shouldRenderSearchableEnvironmentsDropdown() {
return this.glFeatures.searchableEnvironmentsDropdown;
},
},
created() {
this.setEndpoints({
......@@ -255,6 +261,7 @@ export default {
'setGettingStartedEmptyState',
'setEndpoints',
'setPanelGroupMetrics',
'setEnvironmentsSearchTerm',
]),
updatePanels(key, panels) {
this.setPanelGroupMetrics({
......@@ -296,6 +303,9 @@ export default {
setFormValidity(isValid) {
this.formIsValid = isValid;
},
debouncedEnvironmentsSearch: _.debounce(function environmentsSearchOnInput(searchTerm) {
this.setEnvironmentsSearchTerm(searchTerm);
}, 500),
submitCustomMetricsForm() {
this.$refs.customMetricsForm.submit();
},
......@@ -374,17 +384,36 @@ export default {
data-qa-selector="environments_dropdown"
class="mb-0 d-flex"
toggle-class="dropdown-menu-toggle"
menu-class="monitor-environment-dropdown-menu"
:text="currentEnvironmentName"
:disabled="environments.length === 0"
:disabled="filteredEnvironments.length === 0"
>
<gl-dropdown-item
v-for="environment in environments"
:key="environment.id"
:active="environment.name === currentEnvironmentName"
active-class="is-active"
:href="environment.metrics_path"
>{{ environment.name }}</gl-dropdown-item
>
<div class="d-flex flex-column overflow-hidden">
<gl-search-box-by-type
v-if="shouldRenderSearchableEnvironmentsDropdown"
ref="monitorEnvironmentsDropdownSearch"
class="m-2"
@input="debouncedEnvironmentsSearch"
/>
<div class="flex-fill overflow-auto">
<gl-dropdown-item
v-for="environment in filteredEnvironments"
:key="environment.id"
:active="environment.name === currentEnvironmentName"
active-class="is-active"
:href="environment.metrics_path"
>{{ environment.name }}</gl-dropdown-item
>
</div>
<div
v-if="shouldRenderSearchableEnvironmentsDropdown"
v-show="filteredEnvironments.length === 0"
ref="monitorEnvironmentsDropdownMsg"
class="text-secondary no-matches-message"
>
{{ s__('No matching results') }}
</div>
</div>
</gl-dropdown>
</gl-form-group>
......@@ -415,18 +444,16 @@ export default {
variant="default"
class="mr-2 mt-1 js-rearrange-button"
@click="toggleRearrangingPanels"
>{{ __('Arrange charts') }}</gl-button
>
{{ __('Arrange charts') }}
</gl-button>
<gl-button
v-if="addingMetricsAvailable"
ref="addMetricBtn"
v-gl-modal="$options.addMetric.modalId"
variant="outline-success"
class="mr-2 mt-1"
>{{ $options.addMetric.title }}</gl-button
>
{{ $options.addMetric.title }}
</gl-button>
<gl-modal
v-if="addingMetricsAvailable"
ref="addMetricModal"
......@@ -448,9 +475,8 @@ export default {
:disabled="!formIsValid"
variant="success"
@click="submitCustomMetricsForm"
>{{ __('Save changes') }}</gl-button
>
{{ __('Save changes') }}
</gl-button>
</div>
</gl-modal>
......@@ -458,9 +484,8 @@ export default {
v-if="selectedDashboard.can_edit"
class="mt-1 js-edit-link"
:href="selectedDashboard.project_blob_path"
>{{ __('Edit dashboard') }}</gl-button
>
{{ __('Edit dashboard') }}
</gl-button>
<gl-button
v-if="externalDashboardUrl.length"
......@@ -506,9 +531,9 @@ export default {
class="draggable-remove js-draggable-remove p-2 w-100 position-absolute d-flex justify-content-end"
@click="removePanel(groupData.key, groupData.panels, graphIndex)"
>
<a class="mx-2 p-2 draggable-remove-link" :aria-label="__('Remove')"
><icon name="close"
/></a>
<a class="mx-2 p-2 draggable-remove-link" :aria-label="__('Remove')">
<icon name="close" />
</a>
</div>
<panel-type
......
......@@ -30,6 +30,10 @@ export const setEndpoints = ({ commit }, endpoints) => {
commit(types.SET_ENDPOINTS, endpoints);
};
export const setEnvironmentsSearchTerm = ({ commit }, searchTerm) => {
commit(types.SET_ENVIRONMENTS_SEARCH_TERM, searchTerm);
};
export const setShowErrorBanner = ({ commit }, enabled) => {
commit(types.SET_SHOW_ERROR_BANNER, enabled);
};
......
......@@ -58,5 +58,20 @@ export const metricsWithData = state => groupKey => {
return res;
};
/**
* Filter environments by names.
*
* This is used in the environments dropdown with searchable input.
* Also, this searchable dropdown is behind `searchable_environments_dropdown`
* feature flag
*
* @param {Object} state
* @returns {Array} List of environments
*/
export const filteredEnvironments = state =>
state.environments.filter(env =>
env.name.toLowerCase().includes((state.environmentsSearchTerm || '').trim().toLowerCase()),
);
// prevent babel-plugin-rewire from generating an invalid default during karma tests
export default () => {};
......@@ -21,3 +21,5 @@ export const SET_GETTING_STARTED_EMPTY_STATE = 'SET_GETTING_STARTED_EMPTY_STATE'
export const SET_NO_DATA_EMPTY_STATE = 'SET_NO_DATA_EMPTY_STATE';
export const SET_SHOW_ERROR_BANNER = 'SET_SHOW_ERROR_BANNER';
export const SET_PANEL_GROUP_METRICS = 'SET_PANEL_GROUP_METRICS';
export const SET_ENVIRONMENTS_SEARCH_TERM = 'SET_ENVIRONMENTS_SEARCH_TERM';
......@@ -196,4 +196,7 @@ export default {
const panelGroup = state.dashboard.panel_groups.find(pg => payload.key === pg.key);
panelGroup.panels = payload.panels;
},
[types.SET_ENVIRONMENTS_SEARCH_TERM](state, searchTerm) {
state.environmentsSearchTerm = searchTerm;
},
};
......@@ -15,6 +15,7 @@ export default () => ({
deploymentData: [],
environments: [],
environmentsSearchTerm: '',
allDashboards: [],
currentDashboard: null,
projectPath: null,
......
......@@ -12,6 +12,7 @@
max-width: 900px;
&.navless-container {
padding: 35px $gl-padding;
// overriding .devise-layout-html.navless-container to support the sticky footer
// without having a header on size xs
@include media-breakpoint-down(xs) {
......@@ -24,6 +25,7 @@
.signup-heading h2 {
font-weight: $gl-font-weight-bold;
padding: 0 $gl-padding;
font-size: $gl-font-size-28;
@include media-breakpoint-down(md) {
font-size: $gl-font-size-large;
......@@ -49,4 +51,35 @@
color: $red-700;
}
}
.omniauth-divider {
&::before,
&::after {
content: '';
flex: 1;
border-bottom: 1px solid $gray-dark;
margin: $gl-padding-24 0;
}
&::before {
margin-right: $gl-padding;
}
&::after {
margin-left: $gl-padding;
}
}
.omniauth-btn {
width: 48%;
@include media-breakpoint-down(md) {
width: 100%;
}
img {
width: $default-icon-size;
height: $default-icon-size;
}
}
}
......@@ -58,6 +58,18 @@
.custom-time-range-form-group > label {
padding-bottom: $gl-padding;
}
.monitor-environment-dropdown-menu {
&.show {
display: flex;
flex-direction: column;
overflow: hidden;
}
.no-matches-message {
padding: $gl-padding-8 $gl-padding-12;
}
}
}
.prometheus-panel {
......
......@@ -14,6 +14,7 @@ class Projects::EnvironmentsController < Projects::ApplicationController
before_action :expire_etag_cache, only: [:index], unless: -> { request.format.json? }
before_action only: [:metrics, :additional_metrics, :metrics_dashboard] do
push_frontend_feature_flag(:prometheus_computed_alerts)
push_frontend_feature_flag(:searchable_environments_dropdown)
end
before_action do
push_frontend_feature_flag(:auto_stop_environments)
......
......@@ -89,7 +89,17 @@ def providers_for_base_controller
def enabled_button_based_providers
disabled_providers = Gitlab::CurrentSettings.disabled_oauth_sign_in_sources || []
button_based_providers.map(&:to_s) - disabled_providers
providers = button_based_providers.map(&:to_s) - disabled_providers
providers.sort_by do |provider|
case provider
when 'google_oauth2'
0
when 'github'
1
else
2
end
end
end
def button_based_providers_enabled?
......
......@@ -394,6 +394,11 @@ def password_length
Gitlab::CurrentSettings.minimum_password_length..Devise.password_length.max
end
# Generate a random password that conforms to the current password length settings
def random_password
Devise.friendly_token(password_length.max)
end
# Devise method overridden to allow sign in with email or username
def find_for_database_authentication(warden_conditions)
conditions = warden_conditions.dup
......
......@@ -38,13 +38,9 @@ def raw_dashboard
# Determines whether users should be able to view
# dashboards at all.
def allowed?
if params[:environment]
Ability.allowed?(current_user, :read_environment, project)
elsif params[:cluster]
true # Authorization handled at controller level
else
false
end
return false unless params[:environment]
Ability.allowed?(current_user, :read_environment, project)
end
# Returns a new dashboard Hash, supplemented with DB info
......
......@@ -23,7 +23,7 @@ def execute(skip_authorization: false)
@reset_token = user.generate_reset_token if params[:reset_password]
if user_params[:force_random_password]
random_password = Devise.friendly_token.first(User.password_length.min)
random_password = User.random_password
user.password = user.password_confirmation = random_password
end
end
......
......@@ -41,3 +41,5 @@
= recaptcha_tags
.submit-container.mt-3
= f.submit _("Register"), class: "btn-register btn btn-block btn-success mb-0 p-2", data: { qa_selector: 'new_user_register_button' }
- if omniauth_enabled? && button_based_providers_enabled?
= render 'devise/shared/experimental_separate_sign_up_flow_omniauth_box'
.omniauth-divider.d-flex.align-items-center.text-center
= _("or")
%label.label-bold.d-block
= _("Create an account using:")
- providers = enabled_button_based_providers
.d-flex.justify-content-between.flex-wrap
- providers.each do |provider|
- has_icon = provider_has_icon?(provider)
= link_to omniauth_authorize_path(:user, provider), method: :post, class: "btn d-flex align-items-center omniauth-btn text-left oauth-login mb-2 p-2 #{qa_class_for_provider(provider)}", id: "oauth-login-#{provider}" do
- if has_icon
= provider_image_tag(provider)
%span.ml-2
= label_for_provider(provider)
......@@ -9,10 +9,10 @@
= render "layouts/broadcast"
.content
= render "layouts/flash"
.row.mb-3
.row.mb-6
.col-sm-8.offset-sm-2.col-md-6.offset-md-3.new-session-forms-container
= render_if_exists 'layouts/devise_help_text'
.text-center.signup-heading.mt-3.mb-3
.text-center.signup-heading.mb-3
= image_tag(image_url('logo.svg'), class: 'gitlab-logo', alt: 'GitLab Logo')
- if content_for?(:page_title)
%h2= yield :page_title
......
---
title: Fixes random passwords generated not conforming to minimum_password_length setting
merge_request: 23387
author:
type: fixed
---
title: Reorder signup omniauth options
merge_request: 23082
author:
type: changed
......@@ -34,7 +34,7 @@ def email
end
def password
@password ||= Gitlab::Utils.force_utf8(Devise.friendly_token[0, 8].downcase)
@password ||= Gitlab::Utils.force_utf8(::User.random_password.downcase)
end
def location
......
......@@ -5361,6 +5361,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
msgid "Create an account using:"
msgstr ""
msgid "Create an issue"
msgstr ""
......@@ -22721,6 +22724,9 @@ msgstr ""
msgid "opened %{timeAgo}"
msgstr ""
msgid "or"
msgstr ""
msgid "out of %d total test"
msgid_plural "out of %d total tests"
msgstr[0] ""
......
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