diff options
Diffstat (limited to 'app/assets')
25 files changed, 212 insertions, 243 deletions
diff --git a/app/assets/javascripts/organizations/profile/preferences/index.js b/app/assets/javascripts/organizations/profile/preferences/index.js index 0b0dd313cd8..11686b62eca 100644 --- a/app/assets/javascripts/organizations/profile/preferences/index.js +++ b/app/assets/javascripts/organizations/profile/preferences/index.js @@ -30,8 +30,8 @@ export const initHomeOrganizationSetting = () => { block: true, label: s__('Organization|Home organization'), description: s__('Organization|Choose what organization you want to see by default.'), - inputName: 'home_organization', - inputId: 'home_organization', + inputName: 'user[home_organization_id]', + inputId: 'user_home_organization_id', initialSelection, toggleClass: 'gl-form-input-xl', }, diff --git a/app/assets/javascripts/persistent_user_callout.js b/app/assets/javascripts/persistent_user_callout.js index 71dc8c3d020..007b1454138 100644 --- a/app/assets/javascripts/persistent_user_callout.js +++ b/app/assets/javascripts/persistent_user_callout.js @@ -22,12 +22,17 @@ export default class PersistentUserCallout { init() { const followLink = this.container.querySelector('.js-follow-link'); + const closeAndFollowLink = this.container.querySelector('.js-close-and-follow-link'); if (this.closeButtons.length) { this.handleCloseButtonCallout(); } else if (followLink) { this.handleFollowLinkCallout(followLink); } + + if (closeAndFollowLink) { + this.handleFollowLinkCallout(closeAndFollowLink); + } } handleCloseButtonCallout() { diff --git a/app/assets/javascripts/persistent_user_callouts.js b/app/assets/javascripts/persistent_user_callouts.js index 39c6d3bd14d..7420542a065 100644 --- a/app/assets/javascripts/persistent_user_callouts.js +++ b/app/assets/javascripts/persistent_user_callouts.js @@ -4,7 +4,6 @@ const PERSISTENT_USER_CALLOUTS = [ '.js-recovery-settings-callout', '.js-users-over-license-callout', '.js-admin-licensed-user-count-threshold', - '.js-buy-pipeline-minutes-notification-callout', '.js-token-expiry-callout', '.js-registration-enabled-callout', '.js-new-user-signups-cap-reached', diff --git a/app/assets/javascripts/projects/settings_service_desk/components/service_desk_root.vue b/app/assets/javascripts/projects/settings_service_desk/components/service_desk_root.vue index 69ea29edc14..a9dca81b9f4 100644 --- a/app/assets/javascripts/projects/settings_service_desk/components/service_desk_root.vue +++ b/app/assets/javascripts/projects/settings_service_desk/components/service_desk_root.vue @@ -53,6 +53,9 @@ export default { projectKey: { default: '', }, + reopenIssueOnExternalParticipantNote: { + default: false, + }, addExternalParticipantsFromCc: { default: false, }, @@ -115,6 +118,7 @@ export default { fileTemplateProjectId, outgoingName, projectKey, + reopenIssueOnExternalParticipantNote, addExternalParticipantsFromCc, }) { this.isTemplateSaving = true; @@ -123,6 +127,7 @@ export default { issue_template_key: selectedTemplate, outgoing_name: outgoingName, project_key: projectKey, + reopen_issue_on_external_participant_note: reopenIssueOnExternalParticipantNote, add_external_participants_from_cc: addExternalParticipantsFromCc, service_desk_enabled: this.isEnabled, file_template_project_id: fileTemplateProjectId, @@ -195,6 +200,7 @@ export default { :initial-selected-file-template-project-id="selectedFileTemplateProjectId" :initial-outgoing-name="outgoingName" :initial-project-key="projectKey" + :initial-reopen-issue-on-external-participant-note="reopenIssueOnExternalParticipantNote" :initial-add-external-participants-from-cc="addExternalParticipantsFromCc" :templates="templates" :is-template-saving="isTemplateSaving" diff --git a/app/assets/javascripts/projects/settings_service_desk/components/service_desk_setting.vue b/app/assets/javascripts/projects/settings_service_desk/components/service_desk_setting.vue index 891ad53dd10..2853a7d8d72 100644 --- a/app/assets/javascripts/projects/settings_service_desk/components/service_desk_setting.vue +++ b/app/assets/javascripts/projects/settings_service_desk/components/service_desk_setting.vue @@ -23,6 +23,12 @@ export default { issueTrackerEnableMessage: __( 'To use Service Desk in this project, you must %{linkStart}activate the issue tracker%{linkEnd}.', ), + reopenIssueOnExternalParticipantNote: { + label: s__('ServiceDesk|Reopen issues when an external participant comments'), + help: s__( + 'ServiceDesk|This also adds an internal comment that mentions the assignees of the issue.', + ), + }, addExternalParticipantsFromCc: { label: s__('ServiceDesk|Add external participants from the %{codeStart}Cc%{codeEnd} header'), help: s__( @@ -91,6 +97,11 @@ export default { required: false, default: '', }, + initialReopenIssueOnExternalParticipantNote: { + type: Boolean, + required: false, + default: false, + }, initialAddExternalParticipantsFromCc: { type: Boolean, required: false, @@ -113,6 +124,7 @@ export default { selectedFileTemplateProjectId: this.initialSelectedFileTemplateProjectId, outgoingName: this.initialOutgoingName || __('GitLab Support Bot'), projectKey: this.initialProjectKey, + reopenIssueOnExternalParticipantNote: this.initialReopenIssueOnExternalParticipantNote, addExternalParticipantsFromCc: this.initialAddExternalParticipantsFromCc, searchTerm: '', projectKeyError: null, @@ -156,6 +168,7 @@ export default { selectedTemplate: this.selectedTemplate, outgoingName: this.outgoingName, projectKey: this.projectKey, + reopenIssueOnExternalParticipantNote: this.reopenIssueOnExternalParticipantNote, addExternalParticipantsFromCc: this.addExternalParticipantsFromCc, fileTemplateProjectId: this.selectedFileTemplateProjectId, }); @@ -323,9 +336,22 @@ export default { </gl-form-group> <gl-form-checkbox + v-model="reopenIssueOnExternalParticipantNote" + :disabled="!isIssueTrackerEnabled" + data-testid="reopen-issue-on-external-participant-note" + > + {{ $options.i18n.reopenIssueOnExternalParticipantNote.label }} + + <template #help> + {{ $options.i18n.reopenIssueOnExternalParticipantNote.help }} + </template> + </gl-form-checkbox> + + <gl-form-checkbox v-if="showAddExternalParticipantsFromCC" v-model="addExternalParticipantsFromCc" :disabled="!isIssueTrackerEnabled" + data-testid="add-external-participants-from-cc" > <gl-sprintf :message="$options.i18n.addExternalParticipantsFromCc.label"> <template #code="{ content }"> diff --git a/app/assets/javascripts/projects/settings_service_desk/index.js b/app/assets/javascripts/projects/settings_service_desk/index.js index ce223b349bf..a3c310ec501 100644 --- a/app/assets/javascripts/projects/settings_service_desk/index.js +++ b/app/assets/javascripts/projects/settings_service_desk/index.js @@ -21,6 +21,7 @@ export default () => { incomingEmail, outgoingName, projectKey, + reopenIssueOnExternalParticipantNote, addExternalParticipantsFromCc, selectedTemplate, selectedFileTemplateProjectId, @@ -40,6 +41,7 @@ export default () => { isIssueTrackerEnabled: parseBoolean(issueTrackerEnabled), outgoingName, projectKey, + reopenIssueOnExternalParticipantNote: parseBoolean(reopenIssueOnExternalParticipantNote), addExternalParticipantsFromCc: parseBoolean(addExternalParticipantsFromCc), selectedTemplate, selectedFileTemplateProjectId: parseInt(selectedFileTemplateProjectId, 10) || null, diff --git a/app/assets/javascripts/repository/commits_service.js b/app/assets/javascripts/repository/commits_service.js index 1e0de045d39..44113788716 100644 --- a/app/assets/javascripts/repository/commits_service.js +++ b/app/assets/javascripts/repository/commits_service.js @@ -31,13 +31,14 @@ const fetchData = (projectPath, path, ref, offset, refType) => { fetchedBatches.push(offset); + const encodePathFunc = gon.features.encodingLogsTree ? encodeURI : encodeURIComponent; const url = joinPaths( gon.relative_url_root || '/', projectPath, '/-/refs/', - encodeURIComponent(ref), + encodePathFunc(ref), '/logs_tree/', - encodeURIComponent(removeLeadingSlash(path)), + encodePathFunc(removeLeadingSlash(path)), ); return axios diff --git a/app/assets/javascripts/search/index.js b/app/assets/javascripts/search/index.js index 5879735d0f6..0c70a3e70f2 100644 --- a/app/assets/javascripts/search/index.js +++ b/app/assets/javascripts/search/index.js @@ -1,30 +1,41 @@ import setHighlightClass from 'ee_else_ce/search/highlight_blob_search_result'; import { queryToObject } from '~/lib/utils/url_utility'; import syntaxHighlight from '~/syntax_highlight'; -import { initSidebar, sidebarInitState } from './sidebar'; +import { initSidebar } from './sidebar'; import { initSearchSort } from './sort'; import createStore from './store'; import { initTopbar } from './topbar'; import { initBlobRefSwitcher } from './under_topbar'; -const topbarInitState = () => { - const el = document.getElementById('js-search-topbar'); +const sidebarInitState = () => { + const el = document.getElementById('js-search-sidebar'); if (!el) return {}; - const { defaultBranchName } = el.dataset; - return { defaultBranchName }; + + const { navigationJson, searchType, groupInitialJson, projectInitialJson } = el.dataset; + + const navigationJsonParsed = JSON.parse(navigationJson); + const groupInitialJsonParsed = JSON.parse(groupInitialJson); + const projectInitialJsonParsed = JSON.parse(projectInitialJson); + + return { navigationJsonParsed, searchType, groupInitialJsonParsed, projectInitialJsonParsed }; }; export const initSearchApp = () => { syntaxHighlight(document.querySelectorAll('.js-search-results')); const query = queryToObject(window.location.search, { gatherArrays: true }); - const { navigationJsonParsed: navigation, searchType } = sidebarInitState() || {}; - const { defaultBranchName } = topbarInitState() || {}; + const { + navigationJsonParsed: navigation, + searchType, + groupInitialJsonParsed: groupInitialJson, + projectInitialJsonParsed: projectInitialJson, + } = sidebarInitState() || {}; const store = createStore({ query, navigation, searchType, - defaultBranchName, + groupInitialJson, + projectInitialJson, }); initTopbar(store); diff --git a/app/assets/javascripts/search/sidebar/components/all_scopes_start_filters.vue b/app/assets/javascripts/search/sidebar/components/all_scopes_start_filters.vue new file mode 100644 index 00000000000..cb017b6898b --- /dev/null +++ b/app/assets/javascripts/search/sidebar/components/all_scopes_start_filters.vue @@ -0,0 +1,19 @@ +<script> +import GroupFilter from './group_filter.vue'; +import ProjectFilter from './project_filter.vue'; + +export default { + name: 'AllScopesStartFilters', + components: { + GroupFilter, + ProjectFilter, + }, +}; +</script> + +<template> + <div class="gl-px-5 gl-pt-6"> + <group-filter class="gl-mb-5" /> + <project-filter class="gl-mb-5" /> + </div> +</template> diff --git a/app/assets/javascripts/search/sidebar/components/app.vue b/app/assets/javascripts/search/sidebar/components/app.vue index 307be0b0aa0..bbee0e441cc 100644 --- a/app/assets/javascripts/search/sidebar/components/app.vue +++ b/app/assets/javascripts/search/sidebar/components/app.vue @@ -25,6 +25,7 @@ import NotesFilters from './notes_filters.vue'; import CommitsFilters from './commits_filters.vue'; import MilestonesFilters from './milestones_filters.vue'; import WikiBlobsFilters from './wiki_blobs_filters.vue'; +import AllScopesStartFilters from './all_scopes_start_filters.vue'; export default { name: 'GlobalSearchSidebar', @@ -40,8 +41,16 @@ export default { DomElementListener, CommitsFilters, MilestonesFilters, + AllScopesStartFilters, }, mixins: [glFeatureFlagsMixin()], + props: { + headerText: { + required: false, + type: String, + default: '', + }, + }, computed: { ...mapState(['searchType']), ...mapGetters(['currentScope']), @@ -82,6 +91,13 @@ export default { <section> <dom-element-listener selector="#js-open-mobile-filters" @click="toggleFiltersFromSidebar" /> <sidebar-portal> + <all-scopes-start-filters /> + <div + v-if="headerText" + class="gl-px-5 gl-pt-3 gl-pb-2 gl-m-0 gl-reset-line-height gl-font-weight-bold gl-font-sm super-sidebar-context-header" + > + {{ headerText }} + </div> <scope-sidebar-navigation /> <issues-filters v-if="showIssuesFilters" /> <merge-requests-filters v-if="showMergeRequestFilters" /> diff --git a/app/assets/javascripts/search/topbar/components/group_filter.vue b/app/assets/javascripts/search/sidebar/components/group_filter.vue index 7f13def8a0f..20231cdda6a 100644 --- a/app/assets/javascripts/search/topbar/components/group_filter.vue +++ b/app/assets/javascripts/search/sidebar/components/group_filter.vue @@ -2,34 +2,27 @@ import { isEmpty } from 'lodash'; // eslint-disable-next-line no-restricted-imports import { mapState, mapActions, mapGetters } from 'vuex'; +import { s__ } from '~/locale'; import { visitUrl, setUrlParams } from '~/lib/utils/url_utility'; import { ANY_OPTION, GROUP_DATA, PROJECT_DATA } from '../constants'; import SearchableDropdown from './searchable_dropdown.vue'; export default { name: 'GroupFilter', + i18n: { + groupFieldLabel: s__('GlobalSearch|Group'), + }, components: { SearchableDropdown, }, - props: { - groupInitialJson: { - type: Object, - required: false, - default: () => ({}), - }, - labelId: { - type: String, - required: false, - default: 'labelId', - }, - }, data() { return { search: '', + labelId: 'group-filter-dropdown-id', }; }, computed: { - ...mapState(['query', 'groups', 'fetchingGroups']), + ...mapState(['query', 'groups', 'fetchingGroups', 'groupInitialJson', 'useSidebarNavigation']), ...mapGetters(['frequentGroups', 'currentScope']), selectedGroup() { return isEmpty(this.groupInitialJson) ? ANY_OPTION : this.groupInitialJson; @@ -73,17 +66,22 @@ export default { </script> <template> - <searchable-dropdown - data-testid="group-filter" - :header-text="$options.GROUP_DATA.headerText" - :name="$options.GROUP_DATA.name" - :loading="fetchingGroups" - :selected-item="selectedGroup" - :items="groups" - :frequent-items="frequentGroups" - :search-handler="fetchGroups" - :label-id="labelId" - @first-open="firstLoad" - @change="handleGroupChange" - /> + <div> + <h5 :id="labelId" class="gl-mt-0 gl-mb-5 gl-font-sm"> + {{ $options.i18n.groupFieldLabel }} + </h5> + <searchable-dropdown + data-testid="group-filter" + :header-text="$options.GROUP_DATA.headerText" + :name="$options.GROUP_DATA.name" + :loading="fetchingGroups" + :selected-item="selectedGroup" + :items="groups" + :frequent-items="frequentGroups" + :search-handler="fetchGroups" + :label-id="labelId" + @first-open="firstLoad" + @change="handleGroupChange" + /> + </div> </template> diff --git a/app/assets/javascripts/search/topbar/components/project_filter.vue b/app/assets/javascripts/search/sidebar/components/project_filter.vue index ecd118a07ac..76983644e60 100644 --- a/app/assets/javascripts/search/topbar/components/project_filter.vue +++ b/app/assets/javascripts/search/sidebar/components/project_filter.vue @@ -2,34 +2,33 @@ import { isEmpty } from 'lodash'; // eslint-disable-next-line no-restricted-imports import { mapState, mapActions, mapGetters } from 'vuex'; +import { s__ } from '~/locale'; import { visitUrl, setUrlParams } from '~/lib/utils/url_utility'; -import { ANY_OPTION, GROUP_DATA, PROJECT_DATA } from '../constants'; +import { ANY_OPTION, GROUP_DATA, PROJECT_DATA } from '~/search/sidebar/constants'; import SearchableDropdown from './searchable_dropdown.vue'; export default { name: 'ProjectFilter', + i18n: { + projectFieldLabel: s__('GlobalSearch|Project'), + }, components: { SearchableDropdown, }, - props: { - projectInitialJson: { - type: Object, - required: false, - default: () => null, - }, - labelId: { - type: String, - required: false, - default: '', - }, - }, data() { return { search: '', + labelId: 'projects-filter-dropdown-id', }; }, computed: { - ...mapState(['query', 'projects', 'fetchingProjects']), + ...mapState([ + 'query', + 'projects', + 'fetchingProjects', + 'projectInitialJson', + 'useSidebarNavigation', + ]), ...mapGetters(['frequentProjects', 'currentScope']), selectedProject() { return isEmpty(this.projectInitialJson) ? ANY_OPTION : this.projectInitialJson; @@ -74,17 +73,22 @@ export default { </script> <template> - <searchable-dropdown - data-testid="project-filter" - :header-text="$options.PROJECT_DATA.headerText" - :name="$options.PROJECT_DATA.name" - :loading="fetchingProjects" - :selected-item="selectedProject" - :items="projects" - :frequent-items="frequentProjects" - :search-handler="fetchProjects" - :label-id="labelId" - @first-open="firstLoad" - @change="handleProjectChange" - /> + <div> + <h5 :id="labelId" class="gl-mt-0 gl-mb-5 gl-font-sm"> + {{ $options.i18n.projectFieldLabel }} + </h5> + <searchable-dropdown + data-testid="project-filter" + :header-text="$options.PROJECT_DATA.headerText" + :name="$options.PROJECT_DATA.name" + :loading="fetchingProjects" + :selected-item="selectedProject" + :items="projects" + :frequent-items="frequentProjects" + :search-handler="fetchProjects" + :label-id="labelId" + @first-open="firstLoad" + @change="handleProjectChange" + /> + </div> </template> diff --git a/app/assets/javascripts/search/sidebar/components/scope_sidebar_navigation.vue b/app/assets/javascripts/search/sidebar/components/scope_sidebar_navigation.vue index f30618ad9b7..874803a720d 100644 --- a/app/assets/javascripts/search/sidebar/components/scope_sidebar_navigation.vue +++ b/app/assets/javascripts/search/sidebar/components/scope_sidebar_navigation.vue @@ -2,6 +2,7 @@ // eslint-disable-next-line no-restricted-imports import { mapActions, mapState, mapGetters } from 'vuex'; import { s__ } from '~/locale'; +import eventHub from '~/super_sidebar/event_hub'; import NavItem from '~/super_sidebar/components/nav_item.vue'; import { NAV_LINK_DEFAULT_CLASSES, NAV_LINK_COUNT_DEFAULT_CLASSES } from '../constants'; @@ -18,6 +19,8 @@ export default { ...mapGetters(['navigationItems']), }, created() { + eventHub.$emit('toggle-menu-header', false); + if (this.urlQuery?.search) { this.fetchSidebarCount(); } diff --git a/app/assets/javascripts/search/topbar/components/searchable_dropdown.vue b/app/assets/javascripts/search/sidebar/components/searchable_dropdown.vue index c1f0bfc59f3..c1f0bfc59f3 100644 --- a/app/assets/javascripts/search/topbar/components/searchable_dropdown.vue +++ b/app/assets/javascripts/search/sidebar/components/searchable_dropdown.vue diff --git a/app/assets/javascripts/search/sidebar/constants/index.js b/app/assets/javascripts/search/sidebar/constants/index.js index 95906c840d7..e3b0db670b5 100644 --- a/app/assets/javascripts/search/sidebar/constants/index.js +++ b/app/assets/javascripts/search/sidebar/constants/index.js @@ -1,3 +1,5 @@ +import { __ } from '~/locale'; + export const SCOPE_ISSUES = 'issues'; export const SCOPE_MERGE_REQUESTS = 'merge_requests'; export const SCOPE_BLOB = 'blobs'; @@ -26,3 +28,23 @@ export const TRACKING_LABEL_RESET = 'Reset Filters'; export const SEARCH_TYPE_BASIC = 'basic'; export const SEARCH_TYPE_ADVANCED = 'advanced'; export const SEARCH_TYPE_ZOEKT = 'zoekt'; + +export const ANY_OPTION = { + id: null, + name: __('Any'), + name_with_namespace: __('Any'), +}; + +export const GROUP_DATA = { + headerText: __('Filter results by group'), + queryParam: 'group_id', + name: 'name', + fullName: 'full_name', +}; + +export const PROJECT_DATA = { + headerText: __('Filter results by project'), + queryParam: 'project_id', + name: 'name', + fullName: 'name_with_namespace', +}; diff --git a/app/assets/javascripts/search/sidebar/index.js b/app/assets/javascripts/search/sidebar/index.js index 3a699355dc9..9a7472ccad3 100644 --- a/app/assets/javascripts/search/sidebar/index.js +++ b/app/assets/javascripts/search/sidebar/index.js @@ -4,27 +4,23 @@ import GlobalSearchSidebar from './components/app.vue'; Vue.use(Translate); -export const sidebarInitState = () => { - const el = document.getElementById('js-search-sidebar'); - if (!el) return {}; - - const { navigationJson, searchType } = el.dataset; - - const navigationJsonParsed = JSON.parse(navigationJson); - - return { navigationJsonParsed, searchType }; -}; - export const initSidebar = (store) => { const el = document.getElementById('js-search-sidebar'); + const hederEl = document.getElementById('super-sidebar-context-header'); + const headerText = hederEl.innerText; if (!el) return false; return new Vue({ el, + name: 'GlobalSearchSidebar', store, render(createElement) { - return createElement(GlobalSearchSidebar); + return createElement(GlobalSearchSidebar, { + props: { + headerText, + }, + }); }, }); }; diff --git a/app/assets/javascripts/search/store/state.js b/app/assets/javascripts/search/store/state.js index a0e4d8c5596..3daa6b9d98c 100644 --- a/app/assets/javascripts/search/store/state.js +++ b/app/assets/javascripts/search/store/state.js @@ -1,7 +1,7 @@ import { cloneDeep } from 'lodash'; import { GROUPS_LOCAL_STORAGE_KEY, PROJECTS_LOCAL_STORAGE_KEY } from './constants'; -const createState = ({ query, navigation, defaultBranchName, searchType }) => ({ +const createState = ({ query, navigation, searchType, groupInitialJson, projectInitialJson }) => ({ urlQuery: cloneDeep(query), query, groups: [], @@ -21,7 +21,8 @@ const createState = ({ query, navigation, defaultBranchName, searchType }) => ({ }, searchLabelString: '', searchType, - defaultBranchName, + groupInitialJson, + projectInitialJson, }); export default createState; diff --git a/app/assets/javascripts/search/topbar/components/app.vue b/app/assets/javascripts/search/topbar/components/app.vue index c604189ee24..555892659fd 100644 --- a/app/assets/javascripts/search/topbar/components/app.vue +++ b/app/assets/javascripts/search/topbar/components/app.vue @@ -3,13 +3,10 @@ import { GlSearchBoxByType, GlButton } from '@gitlab/ui'; // eslint-disable-next-line no-restricted-imports import { mapState, mapActions } from 'vuex'; import { s__ } from '~/locale'; -import { parseBoolean } from '~/lib/utils/common_utils'; import MarkdownDrawer from '~/vue_shared/components/markdown_drawer/markdown_drawer.vue'; import { ZOEKT_SEARCH_TYPE, ADVANCED_SEARCH_TYPE } from '~/search/store/constants'; import { SYNTAX_OPTIONS_ADVANCED_DOCUMENT, SYNTAX_OPTIONS_ZOEKT_DOCUMENT } from '../constants'; import SearchTypeIndicator from './search_type_indicator.vue'; -import GroupFilter from './group_filter.vue'; -import ProjectFilter from './project_filter.vue'; export default { name: 'GlobalSearchTopbar', @@ -23,22 +20,10 @@ export default { components: { GlButton, GlSearchBoxByType, - GroupFilter, - ProjectFilter, MarkdownDrawer, SearchTypeIndicator, }, props: { - groupInitialJson: { - type: Object, - required: false, - default: () => ({}), - }, - projectInitialJson: { - type: Object, - required: false, - default: () => ({}), - }, defaultBranchName: { type: String, required: false, @@ -55,9 +40,6 @@ export default { this.setQuery({ key: 'search', value }); }, }, - showFilters() { - return !parseBoolean(this.query.snippets); - }, showSyntaxOptions() { return ( (this.searchType === ZOEKT_SEARCH_TYPE || this.searchType === ADVANCED_SEARCH_TYPE) && @@ -103,31 +85,17 @@ export default { </template> <search-type-indicator /> </div> - <div class="search-page-form gl-lg-display-flex gl-flex-direction-row gl-align-items-flex-end"> - <div class="gl-flex-grow-1 gl-lg-mb-0 gl-lg-mr-2"> - <gl-search-box-by-type - id="dashboard_search" - v-model="search" - name="search" - :placeholder="$options.i18n.searchPlaceholder" - @submit="applyQuery" - @keydown.enter.stop.prevent="applyQuery" - /> - </div> - <div v-if="showFilters" class="gl-mb-4 gl-lg-mb-0 gl-lg-mx-3 gl-min-w-20"> - <label id="groupfilterDropdown" class="gl-display-block gl-mb-1 gl-md-pb-2">{{ - $options.i18n.groupFieldLabel - }}</label> - <group-filter label-id="groupfilterDropdown" :group-initial-json="groupInitialJson" /> - </div> - <div v-if="showFilters" class="gl-mb-4 gl-lg-mb-0 gl-lg-ml-3 gl-min-w-20"> - <label id="projectfilterDropdown" class="gl-display-block gl-mb-1 gl-md-pb-2">{{ - $options.i18n.projectFieldLabel - }}</label> - <project-filter - label-id="projectfilterDropdown" - :project-initial-json="projectInitialJson" - /> + <div class="search-page-form gl-lg-display-flex gl-flex-direction-column"> + <div class="gl-lg-display-flex gl-flex-direction-row gl-align-items-flex-start"> + <div class="gl-flex-grow-1 gl-pb-8 gl-lg-mb-0 gl-lg-mr-2"> + <gl-search-box-by-type + id="dashboard_search" + v-model="search" + name="search" + :placeholder="$options.i18n.searchPlaceholder" + @keydown.enter.stop.prevent="applyQuery" + /> + </div> </div> </div> </section> diff --git a/app/assets/javascripts/search/topbar/constants.js b/app/assets/javascripts/search/topbar/constants.js index 279f315f89f..2bd0a4d2c66 100644 --- a/app/assets/javascripts/search/topbar/constants.js +++ b/app/assets/javascripts/search/topbar/constants.js @@ -1,25 +1,3 @@ -import { __ } from '~/locale'; - -export const ANY_OPTION = Object.freeze({ - id: null, - name: __('Any'), - name_with_namespace: __('Any'), -}); - -export const GROUP_DATA = { - headerText: __('Filter results by group'), - queryParam: 'group_id', - name: 'name', - fullName: 'full_name', -}; - -export const PROJECT_DATA = { - headerText: __('Filter results by project'), - queryParam: 'project_id', - name: 'name', - fullName: 'name_with_namespace', -}; - export const SYNTAX_OPTIONS_ADVANCED_DOCUMENT = 'drawers/drawers/advanced_search_syntax.md'; export const SYNTAX_OPTIONS_ZOEKT_DOCUMENT = 'drawers/drawers/exact_code_search_syntax.md'; diff --git a/app/assets/javascripts/search/topbar/index.js b/app/assets/javascripts/search/topbar/index.js index 95e15afd597..6aac91a40d3 100644 --- a/app/assets/javascripts/search/topbar/index.js +++ b/app/assets/javascripts/search/topbar/index.js @@ -11,19 +11,16 @@ export const initTopbar = (store) => { return false; } - const { groupInitialJson, projectInitialJson } = el.dataset; - - const groupInitialJsonParsed = JSON.parse(groupInitialJson); - const projectInitialJsonParsed = JSON.parse(projectInitialJson); + const { defaultBranchName } = el.dataset; return new Vue({ el, + name: 'GlobalSearchTopbar', store, render(createElement) { return createElement(GlobalSearchTopbar, { props: { - groupInitialJson: groupInitialJsonParsed, - projectInitialJson: projectInitialJsonParsed, + defaultBranchName, }, }); }, diff --git a/app/assets/javascripts/search/under_topbar/index.js b/app/assets/javascripts/search/under_topbar/index.js index 8e50c6655dd..0be803d68fd 100644 --- a/app/assets/javascripts/search/under_topbar/index.js +++ b/app/assets/javascripts/search/under_topbar/index.js @@ -14,6 +14,7 @@ export const initBlobRefSwitcher = () => { return new Vue({ el, + name: 'GlobalSearchUnderTopbar', render(createElement) { return createElement(RefSelector, { props: { diff --git a/app/assets/javascripts/super_sidebar/components/super_sidebar.vue b/app/assets/javascripts/super_sidebar/components/super_sidebar.vue index 3beec4ccc14..f2970f05ebc 100644 --- a/app/assets/javascripts/super_sidebar/components/super_sidebar.vue +++ b/app/assets/javascripts/super_sidebar/components/super_sidebar.vue @@ -7,6 +7,7 @@ import { TAB_KEY_CODE } from '~/lib/utils/keycodes'; import { keysFor, TOGGLE_SUPER_SIDEBAR } from '~/behaviors/shortcuts/keybindings'; import { __, s__ } from '~/locale'; import Tracking from '~/tracking'; +import eventHub from '../event_hub'; import { sidebarState, SUPER_SIDEBAR_PEEK_STATE_CLOSED as STATE_CLOSED, @@ -58,6 +59,7 @@ export default { showPeekHint: false, isMouseover: false, breakpoint: null, + showSuperSidebarContextHeader: true, }; }, computed: { @@ -96,6 +98,7 @@ export default { mounted() { this.setupFocusTrapListener(); Mousetrap.bind(keysFor(TOGGLE_SUPER_SIDEBAR), this.toggleSidebar); + eventHub.$on('toggle-menu-header', this.onToggleMenuHeader); }, beforeDestroy() { document.removeEventListener('keydown', this.focusTrap); @@ -166,6 +169,9 @@ export default { event.preventDefault(); } }, + onToggleMenuHeader(forceState) { + this.showSuperSidebarContextHeader = forceState; + }, }, }; </script> @@ -207,6 +213,7 @@ export default { > <scroll-scrim class="gl-flex-grow-1" data-testid="nav-container"> <div + v-if="showSuperSidebarContextHeader" id="super-sidebar-context-header" class="gl-px-5 gl-pt-3 gl-pb-2 gl-m-0 gl-reset-line-height gl-font-weight-bold gl-font-sm super-sidebar-context-header" > diff --git a/app/assets/stylesheets/framework/animations.scss b/app/assets/stylesheets/framework/animations.scss index c93ef2287a8..3512f059911 100644 --- a/app/assets/stylesheets/framework/animations.scss +++ b/app/assets/stylesheets/framework/animations.scss @@ -92,8 +92,7 @@ @include transition(background-color, border-color, color, box-shadow); } -.dropdown-menu-toggle, -.header-user-avatar { +.dropdown-menu-toggle { @include transition(border-color); } diff --git a/app/assets/stylesheets/framework/dropdowns.scss b/app/assets/stylesheets/framework/dropdowns.scss index 0ae88f579e6..e791a0dbbbd 100644 --- a/app/assets/stylesheets/framework/dropdowns.scss +++ b/app/assets/stylesheets/framework/dropdowns.scss @@ -810,14 +810,6 @@ .navbar-gitlab { li.dropdown { position: static; - - &.user-counter { - margin-left: 8px !important; - - > a { - padding: 0 4px !important; - } - } } } diff --git a/app/assets/stylesheets/framework/header.scss b/app/assets/stylesheets/framework/header.scss index 9608e294d30..2265d425e1f 100644 --- a/app/assets/stylesheets/framework/header.scss +++ b/app/assets/stylesheets/framework/header.scss @@ -98,12 +98,6 @@ .container-fluid { padding: 0; - .user-counter { - svg { - margin-right: 3px; - } - } - .navbar-nav { @include media-breakpoint-down(xs) { display: flex; @@ -120,12 +114,6 @@ } .nav > li { - &.header-user { - @include media-breakpoint-down(xs) { - padding-left: 10px; - } - } - > a { will-change: color; margin: 4px 0; @@ -137,38 +125,11 @@ padding: 0; } } - - &.header-user-dropdown-toggle { - margin-left: 2px; - - .header-user-avatar { - margin-right: 0; - } - } } .header-new-dropdown-toggle { margin-right: 0; } - - .impersonated-user, - .impersonated-user:hover { - margin-right: 1px; - background-color: $white; - border-top-right-radius: 0; - border-bottom-right-radius: 0; - } - - .impersonation-btn, - .impersonation-btn:hover { - background-color: $white; - border-top-left-radius: 0; - border-bottom-left-radius: 0; - - svg { - color: $orange-500; - } - } } } } @@ -223,10 +184,6 @@ top: -1px; font-size: 10px; } - - .impersonation i { - color: $red-500; - } } .caret-down, @@ -238,7 +195,6 @@ fill: currentColor; } -.header-user .dropdown-menu, .header-new .dropdown-menu { margin-top: $dropdown-vertical-offset; } @@ -304,44 +260,6 @@ } } } - - .header-user-dropdown-toggle { - text-align: center; - } - - .header-user-avatar { - float: none; - } -} - -.header-user { - &.show .dropdown-menu { - margin-top: 4px; - color: var(--gl-text-color, $gl-text-color); - left: auto; - max-height: $dropdown-max-height-lg; - - .user-status { - max-width: 240px; - } - - svg { - vertical-align: text-top; - } - - a.ci-minutes-emoji gl-emoji, - a.trial-link gl-emoji { - font-size: $gl-font-size; - vertical-align: baseline; - } - } -} - -.header-user-avatar { - float: left; - margin-right: 5px; - border-radius: 50%; - border: 1px solid $gray-normal; } .notification-dot { |