diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-09-15 06:10:08 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-09-15 06:10:08 +0300 |
commit | 1631795942db55d39afe4aa2ce8fe103f87f1a89 (patch) | |
tree | 4f93ffce9d5f3a3ad47eea1322c6c75e31fe9ee8 /app/assets/javascripts/super_sidebar | |
parent | 75776b02d47741e4b32178b22b542da082584d2d (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/super_sidebar')
11 files changed, 0 insertions, 763 deletions
diff --git a/app/assets/javascripts/super_sidebar/components/context_header.vue b/app/assets/javascripts/super_sidebar/components/context_header.vue deleted file mode 100644 index 11b9840a409..00000000000 --- a/app/assets/javascripts/super_sidebar/components/context_header.vue +++ /dev/null @@ -1,56 +0,0 @@ -<script> -import { GlTruncate, GlAvatar, GlIcon } from '@gitlab/ui'; - -export default { - components: { - GlTruncate, - GlAvatar, - GlIcon, - }, - props: { - /* - * Contains metadata about the current view, e.g. `id`, `title` and `avatar` - */ - context: { - type: Object, - required: true, - }, - tag: { - type: String, - required: false, - default: 'div', - }, - }, - computed: { - avatarShape() { - return this.context.avatar_shape || 'rect'; - }, - }, -}; -</script> - -<template> - <component - :is="tag" - class="border-top border-bottom gl-border-gray-a-08! gl-display-flex gl-align-items-center gl-gap-3 gl-font-weight-bold gl-w-full gl-h-8 gl-px-4 gl-flex-shrink-0" - > - <span - v-if="context.icon" - class="gl-avatar avatar-container gl-bg-t-gray-a-08 icon-avatar rect-avatar s24" - > - <gl-icon class="gl-text-gray-700" :name="context.icon" :size="16" /> - </span> - <gl-avatar - v-else - :size="24" - :shape="avatarShape" - :entity-name="context.title" - :entity-id="context.id" - :src="context.avatar" - /> - <div class="gl-flex-grow-1 gl-overflow-auto gl-text-gray-900"> - <gl-truncate :text="context.title" /> - </div> - <slot name="end"></slot> - </component> -</template> diff --git a/app/assets/javascripts/super_sidebar/components/context_switcher.vue b/app/assets/javascripts/super_sidebar/components/context_switcher.vue deleted file mode 100644 index d4aa11b6e04..00000000000 --- a/app/assets/javascripts/super_sidebar/components/context_switcher.vue +++ /dev/null @@ -1,209 +0,0 @@ -<script> -import * as Sentry from '@sentry/browser'; -import { GlDisclosureDropdown, GlSearchBoxByType, GlLoadingIcon, GlAlert } from '@gitlab/ui'; -import { s__ } from '~/locale'; -import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants'; -import searchUserProjectsAndGroups from '../graphql/queries/search_user_groups_and_projects.query.graphql'; -import { trackContextAccess, formatContextSwitcherItems } from '../utils'; -import NavItem from './nav_item.vue'; -import ProjectsList from './projects_list.vue'; -import GroupsList from './groups_list.vue'; -import ContextSwitcherToggle from './context_switcher_toggle.vue'; - -export default { - i18n: { - contextNavigation: s__('Navigation|Context navigation'), - switchTo: s__('Navigation|Switch context'), - searchPlaceholder: s__('Navigation|Search your projects or groups'), - searchingLabel: s__('Navigation|Retrieving search results'), - searchError: s__('Navigation|There was an error fetching search results.'), - }, - apollo: { - groupsAndProjects: { - query: searchUserProjectsAndGroups, - manual: true, - variables() { - return { - username: this.username, - search: this.searchString, - }; - }, - result(response) { - this.hasError = false; - try { - const { - data: { - projects: { nodes: projects }, - user: { - groups: { nodes: groups }, - }, - }, - } = response; - - this.projects = formatContextSwitcherItems(projects); - this.groups = formatContextSwitcherItems(groups); - } catch (e) { - this.handleError(e); - } - }, - error(e) { - this.handleError(e); - }, - skip() { - return !this.searchString; - }, - }, - }, - components: { - GlDisclosureDropdown, - ContextSwitcherToggle, - GlSearchBoxByType, - GlLoadingIcon, - GlAlert, - NavItem, - ProjectsList, - GroupsList, - }, - inject: ['contextSwitcherLinks'], - props: { - username: { - type: String, - required: true, - }, - projectsPath: { - type: String, - required: true, - }, - groupsPath: { - type: String, - required: true, - }, - currentContext: { - type: Object, - required: false, - default: () => ({}), - }, - contextHeader: { - type: Object, - required: true, - }, - }, - data() { - return { - searchString: '', - projects: [], - groups: [], - hasError: false, - isOpen: false, - }; - }, - computed: { - isSearch() { - return Boolean(this.searchString); - }, - isSearching() { - return this.$apollo.queries.groupsAndProjects.loading; - }, - }, - watch: { - isOpen(isOpen) { - this.$emit('toggle', isOpen); - - if (isOpen) { - this.focusInput(); - } - }, - }, - created() { - if (this.currentContext.namespace) { - trackContextAccess(this.username, this.currentContext); - } - }, - methods: { - close() { - this.$refs['disclosure-dropdown'].close(); - }, - focusInput() { - this.$refs['search-box'].focusInput(); - }, - handleError(e) { - Sentry.captureException(e); - this.hasError = true; - }, - onDisclosureDropdownShown() { - this.isOpen = true; - }, - onDisclosureDropdownHidden() { - this.isOpen = false; - }, - }, - DEFAULT_DEBOUNCE_AND_THROTTLE_MS, -}; -</script> - -<template> - <gl-disclosure-dropdown - ref="disclosure-dropdown" - class="context-switcher gl-w-full" - placement="center" - @shown="onDisclosureDropdownShown" - @hidden="onDisclosureDropdownHidden" - > - <template #toggle> - <context-switcher-toggle :context="contextHeader" :expanded="isOpen" /> - </template> - <div aria-hidden="true" class="gl-font-sm gl-font-weight-bold gl-px-4 gl-pt-3 gl-pb-4"> - {{ $options.i18n.switchTo }} - </div> - <div class="gl-p-1 gl-border-t gl-border-b gl-border-gray-50 gl-bg-white"> - <gl-search-box-by-type - ref="search-box" - v-model="searchString" - class="context-switcher-search-box" - :placeholder="$options.i18n.searchPlaceholder" - :debounce="$options.DEFAULT_DEBOUNCE_AND_THROTTLE_MS" - borderless - /> - </div> - <gl-loading-icon - v-if="isSearching" - class="gl-mt-5" - size="md" - :label="$options.i18n.searchingLabel" - /> - <gl-alert v-else-if="hasError" variant="danger" :dismissible="false" class="gl-m-2"> - {{ $options.i18n.searchError }} - </gl-alert> - <nav v-else :aria-label="$options.i18n.contextNavigation" data-testid="context-navigation"> - <ul class="gl-p-0 gl-m-0 gl-list-style-none"> - <li v-if="!isSearch"> - <ul - :aria-label="$options.i18n.switchTo" - class="gl-border-b gl-border-gray-50 gl-px-0 gl-py-2" - > - <nav-item - v-for="item in contextSwitcherLinks" - :key="item.link" - :item="item" - :link-classes="{ [item.link_classes]: item.link_classes }" - is-subitem - /> - </ul> - </li> - <projects-list - :username="username" - :view-all-link="projectsPath" - :is-search="isSearch" - :search-results="projects" - /> - <groups-list - class="gl-border-t gl-border-gray-50" - :username="username" - :view-all-link="groupsPath" - :is-search="isSearch" - :search-results="groups" - /> - </ul> - </nav> - </gl-disclosure-dropdown> -</template> diff --git a/app/assets/javascripts/super_sidebar/components/context_switcher_toggle.vue b/app/assets/javascripts/super_sidebar/components/context_switcher_toggle.vue deleted file mode 100644 index faa7eba6470..00000000000 --- a/app/assets/javascripts/super_sidebar/components/context_switcher_toggle.vue +++ /dev/null @@ -1,43 +0,0 @@ -<script> -import { GlIcon } from '@gitlab/ui'; -import ContextHeader from './context_header.vue'; - -export default { - components: { - GlIcon, - ContextHeader, - }, - props: { - /* - * Contains metadata about the current view, e.g. `id`, `title` and `avatar` - */ - context: { - type: Object, - required: true, - }, - expanded: { - type: Boolean, - required: true, - }, - }, - computed: { - collapseIcon() { - return this.expanded ? 'chevron-up' : 'chevron-down'; - }, - }, -}; -</script> - -<template> - <context-header - :context="context" - tag="button" - type="button" - class="context-switcher-toggle gl-p-0 gl-bg-transparent gl-hover-bg-t-gray-a-08 gl-focus-bg-t-gray-a-08 gl-border-0 gl-box-shadow-none gl-text-left" - data-testid="context-switcher" - > - <template #end> - <gl-icon class="gl-text-gray-400" :name="collapseIcon" /> - </template> - </context-header> -</template> diff --git a/app/assets/javascripts/super_sidebar/components/frequent_items_list.vue b/app/assets/javascripts/super_sidebar/components/frequent_items_list.vue deleted file mode 100644 index fe1a907bd91..00000000000 --- a/app/assets/javascripts/super_sidebar/components/frequent_items_list.vue +++ /dev/null @@ -1,106 +0,0 @@ -<script> -import { GlButton, GlTooltipDirective } from '@gitlab/ui'; -import { __ } from '~/locale'; -import { - getItemsFromLocalStorage, - removeItemFromLocalStorage, - formatContextSwitcherItems, -} from '../utils'; -import ItemsList from './items_list.vue'; - -export default { - components: { - GlButton, - ItemsList, - }, - directives: { - GlTooltip: GlTooltipDirective, - }, - props: { - title: { - type: String, - required: true, - }, - pristineText: { - type: String, - required: true, - }, - storageKey: { - type: String, - required: true, - }, - maxItems: { - type: Number, - required: true, - }, - }, - data() { - return { - cachedFrequentItems: [], - }; - }, - computed: { - isEmpty() { - return !this.cachedFrequentItems.length; - }, - }, - created() { - this.cachedFrequentItems = formatContextSwitcherItems( - getItemsFromLocalStorage({ - storageKey: this.storageKey, - maxItems: this.maxItems, - }), - ); - }, - methods: { - handleItemRemove(item) { - removeItemFromLocalStorage({ - storageKey: this.storageKey, - item, - }); - - this.cachedFrequentItems = this.cachedFrequentItems.filter((i) => i.id !== item.id); - }, - }, - i18n: { - removeItem: __('Remove'), - }, -}; -</script> - -<template> - <li class="gl-py-3"> - <div - data-testid="list-title" - aria-hidden="true" - class="gl-display-flex gl-align-items-center gl-text-transform-uppercase gl-text-secondary gl-font-weight-semibold gl-font-xs gl-line-height-12 gl-letter-spacing-06em gl-my-3" - > - <span class="gl-flex-grow-1 gl-px-3">{{ title }}</span> - </div> - <div - v-if="isEmpty" - data-testid="empty-text" - class="gl-text-gray-500 gl-font-sm gl-my-3 gl-mx-3" - > - {{ pristineText }} - </div> - <items-list :aria-label="title" :items="cachedFrequentItems"> - <template #actions="{ item }"> - <gl-button - v-gl-tooltip.right.viewport - size="small" - category="tertiary" - icon="dash" - class="show-on-focus-or-hover--target" - :aria-label="$options.i18n.removeItem" - :title="$options.i18n.removeItem" - data-testid="item-remove" - @click.stop.prevent="handleItemRemove(item)" - /> - </template> - <template #view-all-items> - <slot name="view-all-items"></slot> - </template> - </items-list> - </li> -</template> diff --git a/app/assets/javascripts/super_sidebar/components/groups_list.vue b/app/assets/javascripts/super_sidebar/components/groups_list.vue deleted file mode 100644 index 48becacebb7..00000000000 --- a/app/assets/javascripts/super_sidebar/components/groups_list.vue +++ /dev/null @@ -1,81 +0,0 @@ -<script> -import { s__ } from '~/locale'; -import { MAX_FREQUENT_GROUPS_COUNT } from '../constants'; -import FrequentItemsList from './frequent_items_list.vue'; -import SearchResults from './search_results.vue'; -import NavItem from './nav_item.vue'; - -export default { - MAX_FREQUENT_GROUPS_COUNT, - components: { - FrequentItemsList, - SearchResults, - NavItem, - }, - props: { - username: { - type: String, - required: true, - }, - viewAllLink: { - type: String, - required: true, - }, - isSearch: { - type: Boolean, - required: false, - default: false, - }, - searchResults: { - type: Array, - required: false, - default: () => [], - }, - }, - computed: { - storageKey() { - return `${this.username}/frequent-groups`; - }, - viewAllProps() { - return { - item: { - link: this.viewAllLink, - title: s__('Navigation|View all your groups'), - icon: 'group', - }, - linkClasses: { 'dashboard-shortcuts-groups': true }, - }; - }, - }, - i18n: { - title: s__('Navigation|Frequently visited groups'), - searchTitle: s__('Navigation|Groups'), - pristineText: s__('Navigation|Groups you visit often will appear here.'), - noResultsText: s__('Navigation|No group matches found'), - }, -}; -</script> - -<template> - <search-results - v-if="isSearch" - :title="$options.i18n.searchTitle" - :no-results-text="$options.i18n.noResultsText" - :search-results="searchResults" - > - <template #view-all-items> - <nav-item v-bind="viewAllProps" is-subitem /> - </template> - </search-results> - <frequent-items-list - v-else - :title="$options.i18n.title" - :storage-key="storageKey" - :max-items="$options.MAX_FREQUENT_GROUPS_COUNT" - :pristine-text="$options.i18n.pristineText" - > - <template #view-all-items> - <nav-item v-bind="viewAllProps" is-subitem /> - </template> - </frequent-items-list> -</template> diff --git a/app/assets/javascripts/super_sidebar/components/items_list.vue b/app/assets/javascripts/super_sidebar/components/items_list.vue deleted file mode 100644 index 1bad13f91e8..00000000000 --- a/app/assets/javascripts/super_sidebar/components/items_list.vue +++ /dev/null @@ -1,44 +0,0 @@ -<script> -import ProjectAvatar from '~/vue_shared/components/project_avatar.vue'; -import NavItem from './nav_item.vue'; - -export default { - components: { - ProjectAvatar, - NavItem, - }, - props: { - items: { - type: Array, - required: false, - default: () => [], - }, - }, -}; -</script> - -<template> - <ul class="gl-p-0 gl-list-style-none"> - <nav-item - v-for="item in items" - :key="item.id" - :item="item" - is-subitem - class="show-on-focus-or-hover--context" - > - <template #icon> - <project-avatar - :project-id="item.id" - :project-name="item.title" - :project-avatar-url="item.avatar" - :size="24" - aria-hidden="true" - /> - </template> - <template #actions> - <slot name="actions" :item="item"></slot> - </template> - </nav-item> - <slot name="view-all-items"></slot> - </ul> -</template> diff --git a/app/assets/javascripts/super_sidebar/components/projects_list.vue b/app/assets/javascripts/super_sidebar/components/projects_list.vue deleted file mode 100644 index 8d1a5c825b5..00000000000 --- a/app/assets/javascripts/super_sidebar/components/projects_list.vue +++ /dev/null @@ -1,82 +0,0 @@ -<script> -import { s__ } from '~/locale'; -import { MAX_FREQUENT_PROJECTS_COUNT } from '../constants'; -import FrequentItemsList from './frequent_items_list.vue'; -import SearchResults from './search_results.vue'; -import NavItem from './nav_item.vue'; - -export default { - MAX_FREQUENT_PROJECTS_COUNT, - components: { - FrequentItemsList, - SearchResults, - NavItem, - }, - props: { - username: { - type: String, - required: true, - }, - viewAllLink: { - type: String, - required: true, - }, - isSearch: { - type: Boolean, - required: false, - default: false, - }, - searchResults: { - type: Array, - required: false, - default: () => [], - }, - }, - computed: { - storageKey() { - return `${this.username}/frequent-projects`; - }, - viewAllProps() { - return { - item: { - link: this.viewAllLink, - title: s__('Navigation|View all your projects'), - icon: 'project', - }, - linkClasses: { 'dashboard-shortcuts-projects': true }, - }; - }, - }, - i18n: { - title: s__('Navigation|Frequently visited projects'), - searchTitle: s__('Navigation|Projects'), - pristineText: s__('Navigation|Projects you visit often will appear here.'), - noResultsText: s__('Navigation|No project matches found'), - }, -}; -</script> - -<template> - <search-results - v-if="isSearch" - class="gl-border-t-0" - :title="$options.i18n.searchTitle" - :no-results-text="$options.i18n.noResultsText" - :search-results="searchResults" - > - <template #view-all-items> - <nav-item v-bind="viewAllProps" is-subitem /> - </template> - </search-results> - <frequent-items-list - v-else - :title="$options.i18n.title" - :storage-key="storageKey" - :max-items="$options.MAX_FREQUENT_PROJECTS_COUNT" - :pristine-text="$options.i18n.pristineText" - > - <template #view-all-items> - <nav-item v-bind="viewAllProps" is-subitem /> - </template> - </frequent-items-list> -</template> diff --git a/app/assets/javascripts/super_sidebar/components/search_results.vue b/app/assets/javascripts/super_sidebar/components/search_results.vue deleted file mode 100644 index ff933f341af..00000000000 --- a/app/assets/javascripts/super_sidebar/components/search_results.vue +++ /dev/null @@ -1,99 +0,0 @@ -<script> -import { GlCollapse, GlCollapseToggleDirective, GlIcon } from '@gitlab/ui'; -import uniqueId from 'lodash/uniqueId'; -import ItemsList from './items_list.vue'; - -export default { - components: { - GlCollapse, - GlIcon, - ItemsList, - }, - directives: { - CollapseToggle: GlCollapseToggleDirective, - }, - props: { - title: { - type: String, - required: true, - }, - noResultsText: { - type: String, - required: true, - }, - searchResults: { - type: Array, - required: false, - default: () => [], - }, - }, - data() { - return { - expanded: true, - }; - }, - computed: { - isEmpty() { - return !this.searchResults.length; - }, - collapseIcon() { - return this.expanded ? 'chevron-up' : 'chevron-down'; - }, - }, - created() { - this.collapseId = uniqueId('expandable-section-'); - }, - buttonClasses: [ - // Reset user agent styles - 'gl-appearance-none', - 'gl-border-0', - 'gl-bg-transparent', - // Text styles - 'gl-text-left', - 'gl-text-transform-uppercase', - 'gl-text-secondary', - 'gl-font-weight-semibold', - 'gl-font-xs', - 'gl-line-height-12', - 'gl-letter-spacing-06em', - // Border - 'gl-border-t', - 'gl-border-gray-50', - // Spacing - 'gl-my-3', - 'gl-pt-2', - // Layout - 'gl-display-flex', - 'gl-justify-content-space-between', - 'gl-align-items-center', - ], -}; -</script> - -<template> - <li class="gl-border-t gl-border-gray-50"> - <button - v-collapse-toggle="collapseId" - :class="$options.buttonClasses" - class="gl-mx-3" - data-testid="search-results-toggle" - > - {{ title }} - <gl-icon :name="collapseIcon" :size="16" /> - </button> - <gl-collapse :id="collapseId" v-model="expanded"> - <div - v-if="isEmpty" - data-testid="empty-text" - class="gl-text-gray-500 gl-font-sm gl-mb-3 gl-mx-4" - > - {{ noResultsText }} - </div> - <items-list :aria-label="title" :items="searchResults"> - <template #view-all-items> - <slot name="view-all-items"></slot> - </template> - </items-list> - </gl-collapse> - </li> -</template> diff --git a/app/assets/javascripts/super_sidebar/graphql/queries/search_user_groups_and_projects.query.graphql b/app/assets/javascripts/super_sidebar/graphql/queries/search_user_groups_and_projects.query.graphql deleted file mode 100644 index 4b1e65be3fa..00000000000 --- a/app/assets/javascripts/super_sidebar/graphql/queries/search_user_groups_and_projects.query.graphql +++ /dev/null @@ -1,24 +0,0 @@ -query searchUserProjectsAndGroups($username: String!, $search: String) { - projects(search: $search, sort: "latest_activity_desc", membership: true, first: 20) { - nodes { - id - name - namespace: nameWithNamespace - webUrl - avatarUrl - } - } - - user(username: $username) { - id - groups(search: $search, first: 20) { - nodes { - id - name - namespace: fullPath - webUrl - avatarUrl - } - } - } -} diff --git a/app/assets/javascripts/super_sidebar/super_sidebar_bundle.js b/app/assets/javascripts/super_sidebar/super_sidebar_bundle.js index 2b62e7a6ede..de16161efb5 100644 --- a/app/assets/javascripts/super_sidebar/super_sidebar_bundle.js +++ b/app/assets/javascripts/super_sidebar/super_sidebar_bundle.js @@ -1,6 +1,4 @@ import Vue from 'vue'; -import VueApollo from 'vue-apollo'; -import createDefaultClient from '~/lib/graphql'; import { convertObjectPropsToCamelCase, parseBoolean } from '~/lib/utils/common_utils'; import { initStatusTriggers } from '../header'; import { JS_TOGGLE_EXPAND_CLASS } from './constants'; @@ -12,12 +10,6 @@ import { import SuperSidebar from './components/super_sidebar.vue'; import SuperSidebarToggle from './components/super_sidebar_toggle.vue'; -Vue.use(VueApollo); - -const apolloProvider = new VueApollo({ - defaultClient: createDefaultClient(), -}); - const getTrialStatusWidgetData = (sidebarData) => { if (sidebarData.trial_status_widget_data_attrs && sidebarData.trial_status_popover_data_attrs) { const { @@ -97,7 +89,6 @@ export const initSuperSidebar = () => { return new Vue({ el, name: 'SuperSidebarRoot', - apolloProvider, provide: { rootPath, toggleNewNavEndpoint, diff --git a/app/assets/javascripts/super_sidebar/utils.js b/app/assets/javascripts/super_sidebar/utils.js index e756651f3c0..97830a32d78 100644 --- a/app/assets/javascripts/super_sidebar/utils.js +++ b/app/assets/javascripts/super_sidebar/utils.js @@ -1,7 +1,6 @@ import * as Sentry from '@sentry/browser'; import AccessorUtilities from '~/lib/utils/accessor'; import { FREQUENT_ITEMS, FIFTEEN_MINUTES_IN_MS } from '~/frequent_items/constants'; -import { truncateNamespace } from '~/lib/utils/text_utility'; import axios from '~/lib/utils/axios_utils'; /** @@ -118,15 +117,6 @@ export const trackContextAccess = (username, context, trackVisitsPath) => { return localStorage.setItem(storageKey, JSON.stringify(storedItems)); }; -export const formatContextSwitcherItems = (items) => - items.map(({ id, name: title, namespace, avatarUrl: avatar, webUrl: link }) => ({ - id, - title, - subtitle: truncateNamespace(namespace), - avatar, - link, - })); - export const getItemsFromLocalStorage = ({ storageKey, maxItems }) => { if (!AccessorUtilities.canUseLocalStorage()) { return []; |