diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-02-12 12:08:48 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-02-12 12:08:48 +0300 |
commit | 7f5e08060f261a63ebf5058a95419da66928173a (patch) | |
tree | b2f77e0445bb28e4eaf156b3d3b71bd46dac8951 /app | |
parent | 22864cafe7a3509342c3c880881ade40ce06f752 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
27 files changed, 199 insertions, 244 deletions
diff --git a/app/assets/javascripts/pages/search/show/refresh_counts.js b/app/assets/javascripts/pages/search/show/refresh_counts.js new file mode 100644 index 00000000000..f3f6312cb7c --- /dev/null +++ b/app/assets/javascripts/pages/search/show/refresh_counts.js @@ -0,0 +1,24 @@ +import axios from '~/lib/utils/axios_utils'; + +function showCount(el, count) { + el.textContent = count; + el.classList.remove('hidden'); +} + +function refreshCount(el) { + const { url } = el.dataset; + + return axios + .get(url) + .then(({ data }) => showCount(el, data.count)) + .catch((e) => { + // eslint-disable-next-line no-console + console.error(`Failed to fetch search count from '${url}'.`, e); + }); +} + +export default function refreshCounts() { + const elements = Array.from(document.querySelectorAll('.js-search-count')); + + return Promise.all(elements.map(refreshCount)); +} diff --git a/app/assets/javascripts/search/index.js b/app/assets/javascripts/search/index.js index 0c5d68ab96b..3050b628cd5 100644 --- a/app/assets/javascripts/search/index.js +++ b/app/assets/javascripts/search/index.js @@ -1,5 +1,6 @@ import setHighlightClass from 'ee_else_ce/search/highlight_blob_search_result'; import Project from '~/pages/projects/project'; +import refreshCounts from '~/pages/search/show/refresh_counts'; import { queryToObject } from '~/lib/utils/url_utility'; import createStore from './store'; import { initTopbar } from './topbar'; @@ -19,5 +20,6 @@ export const initSearchApp = () => { initSearchSort(store); setHighlightClass(query.search); // Code Highlighting + refreshCounts(); // Other Scope Tab Counts Project.initRefSwitcher(); // Code Search Branch Picker }; diff --git a/app/assets/javascripts/search/store/actions.js b/app/assets/javascripts/search/store/actions.js index e1722d8dee3..bdfe966d990 100644 --- a/app/assets/javascripts/search/store/actions.js +++ b/app/assets/javascripts/search/store/actions.js @@ -1,30 +1,9 @@ -import axios from '~/lib/utils/axios_utils'; import Api from '~/api'; import createFlash from '~/flash'; import { __ } from '~/locale'; import { visitUrl, setUrlParams } from '~/lib/utils/url_utility'; import * as types from './mutation_types'; -/* private */ -const getCount = ({ params, state, activeCount }) => { - const globalSearchCountsPath = '/search/count'; - const url = Api.buildUrl(globalSearchCountsPath); - - // count is known for active tab, so return it and skip the Api call - if (params.scope === state.query?.scope) { - return { scope: params.scope, count: activeCount }; - } - - return axios - .get(url, { params }) - .then(({ data }) => { - return { scope: params.scope, count: data.count }; - }) - .catch((e) => { - throw e; - }); -}; - export const fetchGroups = ({ commit }, search) => { commit(types.REQUEST_GROUPS); Api.groups(search) @@ -59,21 +38,6 @@ export const fetchProjects = ({ commit, state }, search) => { } }; -export const fetchSearchCounts = ({ commit, state }, { scopeTabs, activeCount }) => { - commit(types.REQUEST_SEARCH_COUNTS, { scopeTabs, activeCount }); - const promises = scopeTabs.map((scope) => - getCount({ params: { ...state.query, scope }, state, activeCount }), - ); - - Promise.all(promises) - .then((data) => { - commit(types.RECEIVE_SEARCH_COUNTS_SUCCESS, data); - }) - .catch(() => { - createFlash({ message: __('There was an error fetching the Search Counts') }); - }); -}; - export const setQuery = ({ commit }, { key, value }) => { commit(types.SET_QUERY, { key, value }); }; @@ -82,22 +46,6 @@ export const applyQuery = ({ state }) => { visitUrl(setUrlParams({ ...state.query, page: null })); }; -export const resetQuery = ({ state }, snippets = false) => { - let defaultQuery = { - page: null, - state: null, - confidential: null, - nav_source: null, - }; - - if (snippets) { - defaultQuery = { - snippets: true, - group_id: null, - project_id: null, - ...defaultQuery, - }; - } - - visitUrl(setUrlParams({ ...state.query, ...defaultQuery })); +export const resetQuery = ({ state }) => { + visitUrl(setUrlParams({ ...state.query, page: null, state: null, confidential: null })); }; diff --git a/app/assets/javascripts/search/store/mutation_types.js b/app/assets/javascripts/search/store/mutation_types.js index 5ba3845bfcc..a6430b53c4f 100644 --- a/app/assets/javascripts/search/store/mutation_types.js +++ b/app/assets/javascripts/search/store/mutation_types.js @@ -6,7 +6,4 @@ export const REQUEST_PROJECTS = 'REQUEST_PROJECTS'; export const RECEIVE_PROJECTS_SUCCESS = 'RECEIVE_PROJECTS_SUCCESS'; export const RECEIVE_PROJECTS_ERROR = 'RECEIVE_PROJECTS_ERROR'; -export const REQUEST_SEARCH_COUNTS = 'REQUEST_SEARCH_COUNTS'; -export const RECEIVE_SEARCH_COUNTS_SUCCESS = 'RECEIVE_SEARCH_COUNTS_SUCCESS'; - export const SET_QUERY = 'SET_QUERY'; diff --git a/app/assets/javascripts/search/store/mutations.js b/app/assets/javascripts/search/store/mutations.js index 57a577060b3..91d7cf66c8f 100644 --- a/app/assets/javascripts/search/store/mutations.js +++ b/app/assets/javascripts/search/store/mutations.js @@ -1,4 +1,3 @@ -import { ALL_SCOPE_TABS } from '~/search/topbar/constants'; import * as types from './mutation_types'; export default { @@ -24,16 +23,6 @@ export default { state.fetchingProjects = false; state.projects = []; }, - [types.REQUEST_SEARCH_COUNTS](state, { scopeTabs, activeCount }) { - state.inflatedScopeTabs = scopeTabs.map((tab) => { - return { ...ALL_SCOPE_TABS[tab], count: tab === state.query?.scope ? activeCount : '' }; - }); - }, - [types.RECEIVE_SEARCH_COUNTS_SUCCESS](state, data) { - state.inflatedScopeTabs = data.map((tab) => { - return { ...ALL_SCOPE_TABS[tab.scope], count: tab.count }; - }); - }, [types.SET_QUERY](state, { key, value }) { state.query[key] = value; }, diff --git a/app/assets/javascripts/search/store/state.js b/app/assets/javascripts/search/store/state.js index 9528b0400a4..9a0d61d0b93 100644 --- a/app/assets/javascripts/search/store/state.js +++ b/app/assets/javascripts/search/store/state.js @@ -4,6 +4,5 @@ const createState = ({ query }) => ({ fetchingGroups: false, projects: [], fetchingProjects: false, - inflatedScopeTabs: [], }); export default createState; diff --git a/app/assets/javascripts/search/topbar/components/app.vue b/app/assets/javascripts/search/topbar/components/app.vue index c858f1fcc42..639cff591c3 100644 --- a/app/assets/javascripts/search/topbar/components/app.vue +++ b/app/assets/javascripts/search/topbar/components/app.vue @@ -3,7 +3,6 @@ import { mapState, mapActions } from 'vuex'; import { GlForm, GlSearchBoxByType, GlButton } from '@gitlab/ui'; import GroupFilter from './group_filter.vue'; import ProjectFilter from './project_filter.vue'; -import ScopeTabs from './scope_tabs.vue'; export default { name: 'GlobalSearchTopbar', @@ -13,7 +12,6 @@ export default { GroupFilter, ProjectFilter, GlButton, - ScopeTabs, }, props: { groupInitialData: { @@ -26,16 +24,6 @@ export default { required: false, default: () => ({}), }, - scopeTabs: { - type: Array, - required: false, - default: () => [], - }, - count: { - type: String, - required: false, - default: '', - }, }, computed: { ...mapState(['query']), @@ -50,9 +38,6 @@ export default { showFilters() { return !this.query.snippets || this.query.snippets === 'false'; }, - showScopeTabs() { - return this.query.search; - }, }, methods: { ...mapActions(['applyQuery', 'setQuery']), @@ -61,31 +46,28 @@ export default { </script> <template> - <section> - <gl-form class="search-page-form" @submit.prevent="applyQuery"> - <section class="gl-lg-display-flex gl-align-items-flex-end"> - <div class="gl-flex-fill-1 gl-mb-4 gl-lg-mb-0 gl-lg-mr-2"> - <label>{{ __('What are you searching for?') }}</label> - <gl-search-box-by-type - id="dashboard_search" - v-model="search" - name="search" - :placeholder="__(`Search for projects, issues, etc.`)" - /> - </div> - <div v-if="showFilters" class="gl-mb-4 gl-lg-mb-0 gl-lg-mx-2"> - <label class="gl-display-block">{{ __('Group') }}</label> - <group-filter :initial-data="groupInitialData" /> - </div> - <div v-if="showFilters" class="gl-mb-4 gl-lg-mb-0 gl-lg-mx-2"> - <label class="gl-display-block">{{ __('Project') }}</label> - <project-filter :initial-data="projectInitialData" /> - </div> - <gl-button class="btn-search gl-lg-ml-2" variant="success" type="submit">{{ - __('Search') - }}</gl-button> - </section> - </gl-form> - <scope-tabs v-if="showScopeTabs" :scope-tabs="scopeTabs" :count="count" /> - </section> + <gl-form class="search-page-form" @submit.prevent="applyQuery"> + <section class="gl-lg-display-flex gl-align-items-flex-end"> + <div class="gl-flex-fill-1 gl-mb-4 gl-lg-mb-0 gl-lg-mr-2"> + <label>{{ __('What are you searching for?') }}</label> + <gl-search-box-by-type + id="dashboard_search" + v-model="search" + name="search" + :placeholder="__(`Search for projects, issues, etc.`)" + /> + </div> + <div v-if="showFilters" class="gl-mb-4 gl-lg-mb-0 gl-lg-mx-2"> + <label class="gl-display-block">{{ __('Group') }}</label> + <group-filter :initial-data="groupInitialData" /> + </div> + <div v-if="showFilters" class="gl-mb-4 gl-lg-mb-0 gl-lg-mx-2"> + <label class="gl-display-block">{{ __('Project') }}</label> + <project-filter :initial-data="projectInitialData" /> + </div> + <gl-button class="btn-search gl-lg-ml-2" variant="success" type="submit">{{ + __('Search') + }}</gl-button> + </section> + </gl-form> </template> diff --git a/app/assets/javascripts/search/topbar/components/scope_tabs.vue b/app/assets/javascripts/search/topbar/components/scope_tabs.vue deleted file mode 100644 index 83264a1b411..00000000000 --- a/app/assets/javascripts/search/topbar/components/scope_tabs.vue +++ /dev/null @@ -1,73 +0,0 @@ -<script> -import { GlTabs, GlTab, GlBadge } from '@gitlab/ui'; -import { mapState, mapActions } from 'vuex'; - -export default { - name: 'ScopeTabs', - components: { - GlTabs, - GlTab, - GlBadge, - }, - props: { - scopeTabs: { - type: Array, - required: true, - }, - count: { - type: String, - required: false, - default: '', - }, - }, - computed: { - ...mapState(['query', 'inflatedScopeTabs']), - }, - created() { - this.fetchSearchCounts({ scopeTabs: this.scopeTabs, activeCount: this.count }); - }, - methods: { - ...mapActions(['fetchSearchCounts', 'setQuery', 'resetQuery']), - handleTabChange(scope) { - this.setQuery({ key: 'scope', value: scope }); - this.resetQuery(scope === 'snippet_titles'); - }, - isTabActive(scope) { - return scope === this.query.scope; - }, - }, -}; -</script> - -<template> - <div> - <gl-tabs - content-class="gl-p-0" - nav-class="search-filter search-nav-tabs gl-display-flex gl-overflow-x-auto" - > - <gl-tab - v-for="tab in inflatedScopeTabs" - :key="tab.scope" - class="gl-display-flex" - :active="isTabActive(tab.scope)" - :data-testid="`tab-${tab.scope}`" - :title-link-attributes="{ 'data-qa-selector': tab.qaSelector }" - title-link-class="gl-white-space-nowrap" - @click="handleTabChange(tab.scope)" - > - <template #title> - <span data-testid="tab-title"> {{ tab.title }} </span> - <gl-badge - v-show="tab.count" - :data-scope="tab.scope" - :data-testid="`badge-${tab.scope}`" - :variant="isTabActive(tab.scope) ? 'neutral' : 'muted'" - size="sm" - > - {{ tab.count }} - </gl-badge> - </template> - </gl-tab> - </gl-tabs> - </div> -</template> diff --git a/app/assets/javascripts/search/topbar/constants.js b/app/assets/javascripts/search/topbar/constants.js index ec65667cde3..3944b2c8374 100644 --- a/app/assets/javascripts/search/topbar/constants.js +++ b/app/assets/javascripts/search/topbar/constants.js @@ -19,17 +19,3 @@ export const PROJECT_DATA = { selectedDisplayValue: 'name_with_namespace', itemsDisplayValue: 'name_with_namespace', }; - -export const ALL_SCOPE_TABS = { - blobs: { scope: 'blobs', title: __('Code'), qaSelector: 'code_tab' }, - issues: { scope: 'issues', title: __('Issues') }, - merge_requests: { scope: 'merge_requests', title: __('Merge requests') }, - milestones: { scope: 'milestones', title: __('Milestones') }, - notes: { scope: 'notes', title: __('Comments') }, - wiki_blobs: { scope: 'wiki_blobs', title: __('Wiki') }, - commits: { scope: 'commits', title: __('Commits') }, - epics: { scope: 'epics', title: __('Epics') }, - users: { scope: 'users', title: __('Users') }, - snippet_titles: { scope: 'snippet_titles', title: __('Titles and Descriptions') }, - projects: { scope: 'projects', title: __('Projects'), qaSelector: 'projects_tab' }, -}; diff --git a/app/assets/javascripts/search/topbar/index.js b/app/assets/javascripts/search/topbar/index.js index f9564b5cfbb..87316e10e8d 100644 --- a/app/assets/javascripts/search/topbar/index.js +++ b/app/assets/javascripts/search/topbar/index.js @@ -11,12 +11,10 @@ export const initTopbar = (store) => { return false; } - let { groupInitialData, projectInitialData, scopeTabs } = el.dataset; - const { count } = el.dataset; + let { groupInitialData, projectInitialData } = el.dataset; groupInitialData = JSON.parse(groupInitialData); projectInitialData = JSON.parse(projectInitialData); - scopeTabs = JSON.parse(scopeTabs); return new Vue({ el, @@ -26,8 +24,6 @@ export const initTopbar = (store) => { props: { groupInitialData, projectInitialData, - scopeTabs, - count, }, }); }, diff --git a/app/assets/stylesheets/pages/search.scss b/app/assets/stylesheets/pages/search.scss index a1961d24bbf..cd99c667001 100644 --- a/app/assets/stylesheets/pages/search.scss +++ b/app/assets/stylesheets/pages/search.scss @@ -2,7 +2,6 @@ $search-dropdown-max-height: 400px; $search-avatar-size: 16px; $search-sidebar-min-width: 240px; $search-sidebar-max-width: 300px; -$search-topbar-min-height: 111px; .search-results { .search-result-row { @@ -20,12 +19,6 @@ $search-topbar-min-height: 111px; } } -.search-topbar { - @include media-breakpoint-up(md) { - min-height: $search-topbar-min-height; - } -} - .search-sidebar { @include media-breakpoint-up(md) { min-width: $search-sidebar-min-width; @@ -33,11 +26,6 @@ $search-topbar-min-height: 111px; } } -.search-nav-tabs { - overflow-y: hidden; - flex-wrap: nowrap; -} - .search form:hover, .file-finder-input:hover, .issuable-search-form:hover, diff --git a/app/controllers/concerns/boards_actions.rb b/app/controllers/concerns/boards_actions.rb index b382e338a78..79e6f027c2f 100644 --- a/app/controllers/concerns/boards_actions.rb +++ b/app/controllers/concerns/boards_actions.rb @@ -34,16 +34,26 @@ module BoardsActions def boards strong_memoize(:boards) do - Boards::ListService.new(parent, current_user).execute + existing_boards = boards_finder.execute + if existing_boards.any? + existing_boards + else + # if no board exists, create one + [board_create_service.execute.payload] + end end end def board strong_memoize(:board) do - boards.find(params[:id]) + board_finder.execute.first end end + def board_type + board_klass.to_type + end + def serializer BoardSerializer.new(current_user: current_user) end diff --git a/app/controllers/concerns/multiple_boards_actions.rb b/app/controllers/concerns/multiple_boards_actions.rb index 370b8c72bfe..5206f5759d8 100644 --- a/app/controllers/concerns/multiple_boards_actions.rb +++ b/app/controllers/concerns/multiple_boards_actions.rb @@ -65,6 +65,7 @@ module MultipleBoardsActions private def redirect_to_recent_board + return unless board_type == Board.to_type return if request.format.json? || !parent.multiple_issue_boards_available? || !latest_visited_board redirect_to board_path(latest_visited_board.board) diff --git a/app/controllers/groups/boards_controller.rb b/app/controllers/groups/boards_controller.rb index b34b826a695..fa109021b7d 100644 --- a/app/controllers/groups/boards_controller.rb +++ b/app/controllers/groups/boards_controller.rb @@ -3,6 +3,7 @@ class Groups::BoardsController < Groups::ApplicationController include BoardsActions include RecordUserLastActivity + include Gitlab::Utils::StrongMemoize before_action :authorize_read_board!, only: [:index, :show] before_action :assign_endpoint_vars @@ -14,6 +15,28 @@ class Groups::BoardsController < Groups::ApplicationController private + def board_klass + Board + end + + def boards_finder + strong_memoize :boards_finder do + Boards::ListService.new(parent, current_user) + end + end + + def board_finder + strong_memoize :board_finder do + Boards::ListService.new(parent, current_user, board_id: params[:id]) + end + end + + def board_create_service + strong_memoize :board_create_service do + Boards::CreateService.new(parent, current_user) + end + end + def assign_endpoint_vars @boards_endpoint = group_boards_path(group) @namespace_path = group.to_param diff --git a/app/controllers/projects/boards_controller.rb b/app/controllers/projects/boards_controller.rb index 51c9bf3699a..d2e5d319f96 100644 --- a/app/controllers/projects/boards_controller.rb +++ b/app/controllers/projects/boards_controller.rb @@ -15,6 +15,28 @@ class Projects::BoardsController < Projects::ApplicationController private + def board_klass + Board + end + + def boards_finder + strong_memoize :boards_finder do + Boards::ListService.new(parent, current_user) + end + end + + def board_finder + strong_memoize :board_finder do + Boards::ListService.new(parent, current_user, board_id: params[:id]) + end + end + + def board_create_service + strong_memoize :board_create_service do + Boards::CreateService.new(parent, current_user) + end + end + def assign_endpoint_vars @boards_endpoint = project_boards_path(project) @bulk_issues_path = bulk_update_project_issues_path(project) diff --git a/app/graphql/resolvers/board_resolver.rb b/app/graphql/resolvers/board_resolver.rb index 582707cc1e4..2c2922c3fbf 100644 --- a/app/graphql/resolvers/board_resolver.rb +++ b/app/graphql/resolvers/board_resolver.rb @@ -13,7 +13,7 @@ module Resolvers def resolve(id: nil) return unless parent - ::Boards::ListService.new(parent, context[:current_user], board_id: extract_board_id(id)).execute(create_default_board: false).first + ::Boards::ListService.new(parent, context[:current_user], board_id: extract_board_id(id)).execute.first rescue ActiveRecord::RecordNotFound nil end diff --git a/app/graphql/resolvers/boards_resolver.rb b/app/graphql/resolvers/boards_resolver.rb index cdb15dc8f37..be2f22175dc 100644 --- a/app/graphql/resolvers/boards_resolver.rb +++ b/app/graphql/resolvers/boards_resolver.rb @@ -16,7 +16,7 @@ module Resolvers return Board.none unless parent - ::Boards::ListService.new(parent, context[:current_user], board_id: extract_board_id(id)).execute(create_default_board: false) + ::Boards::ListService.new(parent, context[:current_user], board_id: extract_board_id(id)).execute rescue ActiveRecord::RecordNotFound Board.none end diff --git a/app/helpers/boards_helper.rb b/app/helpers/boards_helper.rb index c827fb4dd95..80b6c62cb0b 100644 --- a/app/helpers/boards_helper.rb +++ b/app/helpers/boards_helper.rb @@ -21,7 +21,8 @@ module BoardsHelper group_id: @group&.id, labels_filter_base_path: build_issue_link_base, labels_fetch_path: labels_fetch_path, - labels_manage_path: labels_manage_path + labels_manage_path: labels_manage_path, + board_type: board.to_type } end diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index 0d43032a184..a2e9952f350 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -511,8 +511,7 @@ module ProjectsHelper commits: :download_code, merge_requests: :read_merge_request, notes: [:read_merge_request, :download_code, :read_issue, :read_snippet], - members: :read_project_member, - wiki_blobs: :read_wiki + members: :read_project_member ) end diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb index 1a5b578cc75..a7acc0cd7db 100644 --- a/app/helpers/search_helper.rb +++ b/app/helpers/search_helper.rb @@ -1,8 +1,16 @@ # frozen_string_literal: true module SearchHelper - PROJECT_SEARCH_TABS = %i{blobs issues merge_requests milestones notes wiki_blobs commits}.freeze - BASIC_SEARCH_TABS = %i{projects issues merge_requests milestones}.freeze + SEARCH_GENERIC_PARAMS = [ + :search, + :scope, + :project_id, + :group_id, + :repository_ref, + :snippets, + :sort, + :force_search_results + ].freeze def search_autocomplete_opts(term) return unless current_user @@ -284,19 +292,27 @@ module SearchHelper Sanitize.clean(str) end - def search_nav_tabs - return [:snippet_titles] if !@project && @show_snippets + def search_filter_link(scope, label, data: {}, search: {}) + search_params = params + .merge(search) + .merge({ scope: scope }) + .permit(SEARCH_GENERIC_PARAMS) - tabs = - if @project - PROJECT_SEARCH_TABS.select { |tab| project_search_tabs?(tab) } - else - BASIC_SEARCH_TABS.dup - end - - tabs << :users if show_user_search_tab? + if @scope == scope + li_class = 'active' + count = @search_results.formatted_count(scope) + else + badge_class = 'js-search-count hidden' + badge_data = { url: search_count_path(search_params) } + end - tabs + content_tag :li, class: li_class, data: data do + link_to search_path(search_params) do + concat label + concat ' ' + concat content_tag(:span, count, class: ['badge badge-pill', badge_class], data: badge_data) + end + end end def search_filter_input_options(type, placeholder = _('Search or filter results...')) diff --git a/app/models/board.rb b/app/models/board.rb index a57d101b30a..85fad762ebe 100644 --- a/app/models/board.rb +++ b/app/models/board.rb @@ -44,6 +44,14 @@ class Board < ApplicationRecord def scoped? false end + + def self.to_type + name.demodulize + end + + def to_type + self.class.to_type + end end Board.prepend_if_ee('EE::Board') diff --git a/app/presenters/ci/pipeline_presenter.rb b/app/presenters/ci/pipeline_presenter.rb index f3bb63b31c3..0c68c33cbbe 100644 --- a/app/presenters/ci/pipeline_presenter.rb +++ b/app/presenters/ci/pipeline_presenter.rb @@ -11,6 +11,9 @@ module Ci { unknown_failure: 'Unknown pipeline failure!', config_error: 'CI/CD YAML configuration error!', external_validation_failure: 'External pipeline validation failed!', + activity_limit_exceeded: 'Pipeline activity limit exceeded!', + size_limit_exceeded: 'Pipeline size limit exceeded!', + job_activity_limit_exceeded: 'Pipeline job activity limit exceeded!', deployments_limit_exceeded: 'Pipeline deployments limit exceeded!' } end diff --git a/app/services/boards/list_service.rb b/app/services/boards/list_service.rb index 729bca6580e..80ceb91f56d 100644 --- a/app/services/boards/list_service.rb +++ b/app/services/boards/list_service.rb @@ -2,9 +2,7 @@ module Boards class ListService < Boards::BaseService - def execute(create_default_board: true) - create_board! if create_default_board && parent.boards.empty? - + def execute find_boards end @@ -18,10 +16,6 @@ module Boards parent.boards.first_board end - def create_board! - Boards::CreateService.new(parent, current_user).execute - end - def find_boards found = if parent.multiple_issue_boards_available? diff --git a/app/services/boards/visits/create_service.rb b/app/services/boards/visits/create_service.rb index e2adf755511..428ed1a8bcc 100644 --- a/app/services/boards/visits/create_service.rb +++ b/app/services/boards/visits/create_service.rb @@ -5,6 +5,7 @@ module Boards class CreateService < Boards::BaseService def execute(board) return unless current_user && Gitlab::Database.read_write? + return unless board.is_a?(Board) # other board types do not support board visits yet if parent.is_a?(Group) BoardGroupRecentVisit.visited!(current_user, board) diff --git a/app/views/search/_category.html.haml b/app/views/search/_category.html.haml new file mode 100644 index 00000000000..f094a6f5e3b --- /dev/null +++ b/app/views/search/_category.html.haml @@ -0,0 +1,35 @@ +- users = capture_haml do + - if show_user_search_tab? + = search_filter_link 'users', _("Users") + +.scrolling-tabs-container.inner-page-scroll-tabs.is-smaller + .fade-left= sprite_icon('chevron-lg-left', size: 12) + .fade-right= sprite_icon('chevron-lg-right', size: 12) + %ul.nav-links.search-filter.scrolling-tabs.nav.nav-tabs + - if @project + - if project_search_tabs?(:blobs) + = search_filter_link 'blobs', _("Code"), data: { qa_selector: 'code_tab' } + - if project_search_tabs?(:issues) + = search_filter_link 'issues', _("Issues") + - if project_search_tabs?(:merge_requests) + = search_filter_link 'merge_requests', _("Merge requests") + - if project_search_tabs?(:milestones) + = search_filter_link 'milestones', _("Milestones") + - if project_search_tabs?(:notes) + = search_filter_link 'notes', _("Comments") + - if project_search_tabs?(:wiki) + = search_filter_link 'wiki_blobs', _("Wiki") + - if project_search_tabs?(:commits) + = search_filter_link 'commits', _("Commits") + = users + + - elsif @show_snippets + = search_filter_link 'snippet_titles', _("Titles and Descriptions"), search: { snippets: true, group_id: nil, project_id: nil } + - else + = search_filter_link 'projects', _("Projects"), data: { qa_selector: 'projects_tab' } + = search_filter_link 'issues', _("Issues") + = search_filter_link 'merge_requests', _("Merge requests") + = search_filter_link 'milestones', _("Milestones") + = render_if_exists 'search/epics_filter_link' + = render_if_exists 'search/category_elasticsearch' + = users diff --git a/app/views/search/show.html.haml b/app/views/search/show.html.haml index c0dca74bb8f..d54310bfa82 100644 --- a/app/views/search/show.html.haml +++ b/app/views/search/show.html.haml @@ -16,6 +16,7 @@ = render_if_exists 'search/form_elasticsearch', attrs: { class: 'mb-2 mb-sm-0 align-self-center' } .gl-mt-3 - #js-search-topbar.search-topbar{ data: { "group-initial-data": @group.to_json, "project-initial-data": project_attributes.to_json, "scope-tabs": search_nav_tabs.to_json, count: @search_results&.formatted_count(@scope) } } + #js-search-topbar{ data: { "group-initial-data": @group.to_json, "project-initial-data": project_attributes.to_json } } - if @search_term + = render 'search/category' = render 'search/results' diff --git a/app/views/shared/boards/_show.html.haml b/app/views/shared/boards/_show.html.haml index e4222d8a4fe..ababbdc7eb9 100644 --- a/app/views/shared/boards/_show.html.haml +++ b/app/views/shared/boards/_show.html.haml @@ -6,7 +6,10 @@ - @no_breadcrumb_container = true - @no_container = true - @content_class = "issue-boards-content js-focus-mode-board" -- breadcrumb_title _("Issue Boards") +- if board.to_type == "EpicBoard" + - breadcrumb_title _("Epic Boards") +- else + - breadcrumb_title _("Issue Boards") - page_title("#{board.name}", _("Boards")) - add_page_specific_style 'page_bundles/boards' |