diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-01-22 12:08:39 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-01-22 12:08:39 +0300 |
commit | 001243986195143c395a9811d8254bbf1b9ebfa1 (patch) | |
tree | 6d6d665154fd38beea6ea7f8985330f956565bb3 /app | |
parent | 83d8c1d61762898eb4e69878f117cbb2ef5be494 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
16 files changed, 155 insertions, 33 deletions
diff --git a/app/assets/javascripts/monitoring/components/dashboard.vue b/app/assets/javascripts/monitoring/components/dashboard.vue index 2c51252be39..f6f119d4463 100644 --- a/app/assets/javascripts/monitoring/components/dashboard.vue +++ b/app/assets/javascripts/monitoring/components/dashboard.vue @@ -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 diff --git a/app/assets/javascripts/monitoring/stores/actions.js b/app/assets/javascripts/monitoring/stores/actions.js index 61cd8621902..6303ed2b82f 100644 --- a/app/assets/javascripts/monitoring/stores/actions.js +++ b/app/assets/javascripts/monitoring/stores/actions.js @@ -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); }; diff --git a/app/assets/javascripts/monitoring/stores/getters.js b/app/assets/javascripts/monitoring/stores/getters.js index a13157c6f87..ed1e3e3ffec 100644 --- a/app/assets/javascripts/monitoring/stores/getters.js +++ b/app/assets/javascripts/monitoring/stores/getters.js @@ -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 () => {}; diff --git a/app/assets/javascripts/monitoring/stores/mutation_types.js b/app/assets/javascripts/monitoring/stores/mutation_types.js index 74068e1d846..73d402ac6df 100644 --- a/app/assets/javascripts/monitoring/stores/mutation_types.js +++ b/app/assets/javascripts/monitoring/stores/mutation_types.js @@ -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'; diff --git a/app/assets/javascripts/monitoring/stores/mutations.js b/app/assets/javascripts/monitoring/stores/mutations.js index 506a30ae619..e14425d7c6c 100644 --- a/app/assets/javascripts/monitoring/stores/mutations.js +++ b/app/assets/javascripts/monitoring/stores/mutations.js @@ -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; + }, }; diff --git a/app/assets/javascripts/monitoring/stores/state.js b/app/assets/javascripts/monitoring/stores/state.js index ee8a85ea222..2c6758dfce2 100644 --- a/app/assets/javascripts/monitoring/stores/state.js +++ b/app/assets/javascripts/monitoring/stores/state.js @@ -15,6 +15,7 @@ export default () => ({ deploymentData: [], environments: [], + environmentsSearchTerm: '', allDashboards: [], currentDashboard: null, projectPath: null, diff --git a/app/assets/stylesheets/pages/experimental_separate_sign_up.scss b/app/assets/stylesheets/pages/experimental_separate_sign_up.scss index 5a80ea79600..aeeb8b7384d 100644 --- a/app/assets/stylesheets/pages/experimental_separate_sign_up.scss +++ b/app/assets/stylesheets/pages/experimental_separate_sign_up.scss @@ -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; + } + } } diff --git a/app/assets/stylesheets/pages/prometheus.scss b/app/assets/stylesheets/pages/prometheus.scss index e20e58e21cf..e759423f6e5 100644 --- a/app/assets/stylesheets/pages/prometheus.scss +++ b/app/assets/stylesheets/pages/prometheus.scss @@ -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 { diff --git a/app/controllers/projects/environments_controller.rb b/app/controllers/projects/environments_controller.rb index 70c4b536854..b4b2bf01831 100644 --- a/app/controllers/projects/environments_controller.rb +++ b/app/controllers/projects/environments_controller.rb @@ -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) diff --git a/app/helpers/auth_helper.rb b/app/helpers/auth_helper.rb index a9c4cfe7dcc..e8d3d5f62cb 100644 --- a/app/helpers/auth_helper.rb +++ b/app/helpers/auth_helper.rb @@ -89,7 +89,17 @@ module AuthHelper 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? diff --git a/app/models/user.rb b/app/models/user.rb index be9f528e1bd..e86c0a1826d 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -394,6 +394,11 @@ class User < ApplicationRecord 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 diff --git a/app/services/metrics/dashboard/base_service.rb b/app/services/metrics/dashboard/base_service.rb index c51c88d776a..40c015dff9c 100644 --- a/app/services/metrics/dashboard/base_service.rb +++ b/app/services/metrics/dashboard/base_service.rb @@ -38,13 +38,9 @@ module Metrics # 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 diff --git a/app/services/users/build_service.rb b/app/services/users/build_service.rb index d18f20bc1db..56631bf2785 100644 --- a/app/services/users/build_service.rb +++ b/app/services/users/build_service.rb @@ -23,7 +23,7 @@ module Users @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 diff --git a/app/views/devise/shared/_experimental_separate_sign_up_flow_box.html.haml b/app/views/devise/shared/_experimental_separate_sign_up_flow_box.html.haml index 4832861445b..7de7dec61b0 100644 --- a/app/views/devise/shared/_experimental_separate_sign_up_flow_box.html.haml +++ b/app/views/devise/shared/_experimental_separate_sign_up_flow_box.html.haml @@ -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' diff --git a/app/views/devise/shared/_experimental_separate_sign_up_flow_omniauth_box.haml b/app/views/devise/shared/_experimental_separate_sign_up_flow_omniauth_box.haml new file mode 100644 index 00000000000..d9143d90430 --- /dev/null +++ b/app/views/devise/shared/_experimental_separate_sign_up_flow_omniauth_box.haml @@ -0,0 +1,13 @@ +.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) diff --git a/app/views/layouts/devise_experimental_separate_sign_up_flow.html.haml b/app/views/layouts/devise_experimental_separate_sign_up_flow.html.haml index 2f05717fc0e..3a5c5399355 100644 --- a/app/views/layouts/devise_experimental_separate_sign_up_flow.html.haml +++ b/app/views/layouts/devise_experimental_separate_sign_up_flow.html.haml @@ -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 |