summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/super_sidebar/components
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/super_sidebar/components')
-rw-r--r--app/assets/javascripts/super_sidebar/components/bottom_bar.vue24
-rw-r--r--app/assets/javascripts/super_sidebar/components/context_switcher.vue83
-rw-r--r--app/assets/javascripts/super_sidebar/components/context_switcher_toggle.vue45
-rw-r--r--app/assets/javascripts/super_sidebar/components/counter.vue48
-rw-r--r--app/assets/javascripts/super_sidebar/components/nav_item.vue37
-rw-r--r--app/assets/javascripts/super_sidebar/components/super_sidebar.vue50
-rw-r--r--app/assets/javascripts/super_sidebar/components/user_bar.vue77
7 files changed, 364 insertions, 0 deletions
diff --git a/app/assets/javascripts/super_sidebar/components/bottom_bar.vue b/app/assets/javascripts/super_sidebar/components/bottom_bar.vue
new file mode 100644
index 00000000000..fea29458f45
--- /dev/null
+++ b/app/assets/javascripts/super_sidebar/components/bottom_bar.vue
@@ -0,0 +1,24 @@
+<script>
+import { GlIcon } from '@gitlab/ui';
+import { __ } from '~/locale';
+
+export default {
+ components: {
+ GlIcon,
+ },
+ i18n: {
+ help: __('Help'),
+ new: __('New'),
+ },
+};
+</script>
+
+<template>
+ <div class="bottom-links gl-p-3">
+ <a href="#" class="gl-text-black-normal"
+ ><gl-icon name="question-o" class="gl-mr-3 gl-text-gray-300 gl-text-black-normal!" />{{
+ $options.i18n.help
+ }}</a
+ >
+ </div>
+</template>
diff --git a/app/assets/javascripts/super_sidebar/components/context_switcher.vue b/app/assets/javascripts/super_sidebar/components/context_switcher.vue
new file mode 100644
index 00000000000..f1ddb8290a0
--- /dev/null
+++ b/app/assets/javascripts/super_sidebar/components/context_switcher.vue
@@ -0,0 +1,83 @@
+<script>
+import { GlAvatar, GlSearchBoxByType } from '@gitlab/ui';
+import { s__ } from '~/locale';
+import { contextSwitcherItems } from '../mock_data';
+import NavItem from './nav_item.vue';
+
+export default {
+ components: {
+ GlAvatar,
+ GlSearchBoxByType,
+ NavItem,
+ },
+ i18n: {
+ contextNavigation: s__('Navigation|Context navigation'),
+ switchTo: s__('Navigation|Switch to...'),
+ recentProjects: s__('Navigation|Recent projects'),
+ recentGroups: s__('Navigation|Recent groups'),
+ },
+ contextSwitcherItems,
+ viewAllProjectsItem: {
+ title: s__('Navigation|View all projects'),
+ link: '/projects',
+ icon: 'project',
+ },
+ viewAllGroupsItem: {
+ title: s__('Navigation|View all groups'),
+ link: '/groups',
+ icon: 'group',
+ },
+};
+</script>
+
+<template>
+ <div>
+ <gl-search-box-by-type />
+ <nav :aria-label="$options.i18n.contextNavigation">
+ <ul class="gl-p-0 gl-list-style-none">
+ <li>
+ <div aria-hidden="true" class="gl-font-weight-bold gl-px-3 gl-py-3">
+ {{ $options.i18n.switchTo }}
+ </div>
+ <ul :aria-label="$options.i18n.switchTo" class="gl-p-0">
+ <nav-item :item="$options.contextSwitcherItems.yourWork" />
+ </ul>
+ </li>
+ <li>
+ <div aria-hidden="true" class="gl-font-weight-bold gl-px-3 gl-py-3">
+ {{ $options.i18n.recentProjects }}
+ </div>
+ <ul :aria-label="$options.i18n.recentProjects" class="gl-p-0">
+ <nav-item
+ v-for="project in $options.contextSwitcherItems.recentProjects"
+ :key="project.title"
+ :item="project"
+ >
+ <template #icon>
+ <gl-avatar shape="rect" :size="32" :src="project.avatar" />
+ </template>
+ </nav-item>
+ <nav-item :item="$options.viewAllProjectsItem" />
+ </ul>
+ </li>
+ <li>
+ <div aria-hidden="true" class="gl-font-weight-bold gl-px-3 gl-py-3">
+ {{ $options.i18n.recentGroups }}
+ </div>
+ <ul :aria-label="$options.i18n.recentGroups" class="gl-p-0">
+ <nav-item
+ v-for="project in $options.contextSwitcherItems.recentGroups"
+ :key="project.title"
+ :item="project"
+ >
+ <template #icon>
+ <gl-avatar shape="rect" :size="32" :src="project.avatar" />
+ </template>
+ </nav-item>
+ <nav-item :item="$options.viewAllGroupsItem" />
+ </ul>
+ </li>
+ </ul>
+ </nav>
+ </div>
+</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
new file mode 100644
index 00000000000..b6f058f7aee
--- /dev/null
+++ b/app/assets/javascripts/super_sidebar/components/context_switcher_toggle.vue
@@ -0,0 +1,45 @@
+<script>
+import { GlTruncate, GlAvatar, GlCollapseToggleDirective, GlIcon } from '@gitlab/ui';
+
+export default {
+ components: {
+ GlTruncate,
+ GlAvatar,
+ GlIcon,
+ },
+ directives: {
+ CollapseToggle: GlCollapseToggleDirective,
+ },
+ props: {
+ context: {
+ type: Object,
+ required: true,
+ },
+ expanded: {
+ type: Boolean,
+ required: true,
+ },
+ },
+ computed: {
+ collapseIcon() {
+ return this.expanded ? 'chevron-up' : 'chevron-down';
+ },
+ },
+};
+</script>
+
+<template>
+ <button
+ v-collapse-toggle.context-switcher
+ type="button"
+ class="context-switcher-toggle gl-bg-transparent gl-border-0 border-top border-bottom gl-border-gray-a-08 gl-box-shadow-none gl-display-flex gl-align-items-center gl-font-weight-bold gl-w-full gl-pl-3 gl-pr-5 gl-h-8"
+ >
+ <gl-avatar :size="32" shape="rect" :src="context.avatar" class="gl-mr-3" />
+ <div class="gl-overflow-auto">
+ <gl-truncate :text="context.title" />
+ </div>
+ <span class="gl-flex-grow-1 gl-text-right">
+ <gl-icon :name="collapseIcon" />
+ </span>
+ </button>
+</template>
diff --git a/app/assets/javascripts/super_sidebar/components/counter.vue b/app/assets/javascripts/super_sidebar/components/counter.vue
new file mode 100644
index 00000000000..d790e61ca31
--- /dev/null
+++ b/app/assets/javascripts/super_sidebar/components/counter.vue
@@ -0,0 +1,48 @@
+<script>
+import { GlIcon } from '@gitlab/ui';
+
+export default {
+ components: {
+ GlIcon,
+ },
+ props: {
+ count: {
+ type: Number,
+ required: true,
+ },
+ href: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ icon: {
+ type: String,
+ required: true,
+ },
+ label: {
+ type: String,
+ required: true,
+ },
+ },
+ computed: {
+ ariaLabel() {
+ return `${this.label} ${this.count}`;
+ },
+ component() {
+ return this.href ? 'a' : 'button';
+ },
+ },
+};
+</script>
+
+<template>
+ <component
+ :is="component"
+ :aria-label="ariaLabel"
+ :href="href"
+ class="counter gl-relative gl-display-inline-block gl-flex-grow-1 gl-text-center gl-py-3 gl-bg-gray-10 gl-rounded-base gl-text-black-normal gl-border gl-border-gray-a-08 gl-font-sm gl-font-weight-bold"
+ >
+ <gl-icon aria-hidden="true" :name="icon" />
+ <span aria-hidden="true">{{ count }}</span>
+ </component>
+</template>
diff --git a/app/assets/javascripts/super_sidebar/components/nav_item.vue b/app/assets/javascripts/super_sidebar/components/nav_item.vue
new file mode 100644
index 00000000000..4fd6918fd6f
--- /dev/null
+++ b/app/assets/javascripts/super_sidebar/components/nav_item.vue
@@ -0,0 +1,37 @@
+<script>
+import { GlIcon } from '@gitlab/ui';
+
+export default {
+ name: 'NavItem',
+ components: {
+ GlIcon,
+ },
+ props: {
+ item: {
+ type: Object,
+ required: true,
+ },
+ },
+};
+</script>
+
+<template>
+ <li>
+ <a
+ :href="item.link"
+ class="gl-display-flex gl-pl-3 gl-py-3 gl-line-height-normal gl-text-black-normal gl-hover-bg-t-gray-a-08"
+ >
+ <div class="gl-mr-3">
+ <slot name="icon">
+ <gl-icon v-if="item.icon" :name="item.icon" />
+ </slot>
+ </div>
+ <div class="gl-pr-3">
+ {{ item.title }}
+ <div v-if="item.subtitle" class="gl-font-sm gl-text-gray-500 gl-mt-1">
+ {{ item.subtitle }}
+ </div>
+ </div>
+ </a>
+ </li>
+</template>
diff --git a/app/assets/javascripts/super_sidebar/components/super_sidebar.vue b/app/assets/javascripts/super_sidebar/components/super_sidebar.vue
new file mode 100644
index 00000000000..e2eac64f5ad
--- /dev/null
+++ b/app/assets/javascripts/super_sidebar/components/super_sidebar.vue
@@ -0,0 +1,50 @@
+<script>
+import { GlCollapse } from '@gitlab/ui';
+import { context } from '../mock_data';
+import UserBar from './user_bar.vue';
+import ContextSwitcherToggle from './context_switcher_toggle.vue';
+import ContextSwitcher from './context_switcher.vue';
+import BottomBar from './bottom_bar.vue';
+
+export default {
+ context,
+ components: {
+ GlCollapse,
+ UserBar,
+ ContextSwitcherToggle,
+ ContextSwitcher,
+ BottomBar,
+ },
+ props: {
+ sidebarData: {
+ type: Object,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ contextSwitcherOpened: false,
+ };
+ },
+};
+</script>
+
+<template>
+ <aside
+ class="super-sidebar gl-fixed gl-bottom-0 gl-left-0 gl-display-flex gl-flex-direction-column gl-bg-gray-10 gl-border-r gl-border-gray-a-08 gl-z-index-9999"
+ data-testid="super-sidebar"
+ >
+ <user-bar :sidebar-data="sidebarData" />
+ <div class="gl-display-flex gl-flex-direction-column gl-flex-grow-1 gl-overflow-hidden">
+ <div class="gl-flex-grow-1 gl-overflow-auto">
+ <context-switcher-toggle :context="$options.context" :expanded="contextSwitcherOpened" />
+ <gl-collapse id="context-switcher" v-model="contextSwitcherOpened">
+ <context-switcher />
+ </gl-collapse>
+ </div>
+ <div class="gl-px-3">
+ <bottom-bar />
+ </div>
+ </div>
+ </aside>
+</template>
diff --git a/app/assets/javascripts/super_sidebar/components/user_bar.vue b/app/assets/javascripts/super_sidebar/components/user_bar.vue
new file mode 100644
index 00000000000..7ee1776bf07
--- /dev/null
+++ b/app/assets/javascripts/super_sidebar/components/user_bar.vue
@@ -0,0 +1,77 @@
+<script>
+import { GlAvatar, GlDropdown, GlIcon } from '@gitlab/ui';
+import { __ } from '~/locale';
+import SafeHtml from '~/vue_shared/directives/safe_html';
+import NewNavToggle from '~/nav/components/new_nav_toggle.vue';
+import logo from '../../../../views/shared/_logo.svg';
+import Counter from './counter.vue';
+
+export default {
+ logo,
+ components: {
+ GlAvatar,
+ GlDropdown,
+ GlIcon,
+ NewNavToggle,
+ Counter,
+ },
+ i18n: {
+ issues: __('Issues'),
+ mergeRequests: __('Merge requests'),
+ todoList: __('To-Do list'),
+ },
+ directives: {
+ SafeHtml,
+ },
+ inject: ['rootPath', 'toggleNewNavEndpoint'],
+ props: {
+ sidebarData: {
+ type: Object,
+ required: true,
+ },
+ },
+};
+</script>
+
+<template>
+ <div class="user-bar">
+ <div class="gl-display-flex gl-align-items-center gl-px-3 gl-py-2 gl-gap-3">
+ <div class="gl-flex-grow-1">
+ <a v-safe-html="$options.logo" :href="rootPath"></a>
+ </div>
+ <gl-dropdown variant="link" no-caret>
+ <template #button-content>
+ <gl-icon name="plus" class="gl-vertical-align-middle gl-text-black-normal" />
+ </template>
+ </gl-dropdown>
+ <button class="gl-border-none">
+ <gl-icon name="search" class="gl-vertical-align-middle" />
+ </button>
+ <gl-dropdown data-testid="user-dropdown" variant="link" no-caret>
+ <template #button-content>
+ <gl-avatar :entity-name="sidebarData.name" :src="sidebarData.avatar_url" :size="32" />
+ </template>
+ <new-nav-toggle :endpoint="toggleNewNavEndpoint" enabled />
+ </gl-dropdown>
+ </div>
+ <div class="gl-display-flex gl-justify-content-space-between gl-px-3 gl-py-2 gl-gap-2">
+ <counter
+ icon="issues"
+ :count="sidebarData.assigned_open_issues_count"
+ :href="sidebarData.issues_dashboard_path"
+ :label="$options.i18n.issues"
+ />
+ <counter
+ icon="merge-request-open"
+ :count="sidebarData.assigned_open_merge_requests_count"
+ :label="$options.i18n.mergeRequests"
+ />
+ <counter
+ icon="todo-done"
+ :count="sidebarData.todos_pending_count"
+ href="/dashboard/todos"
+ :label="$options.i18n.todoList"
+ />
+ </div>
+ </div>
+</template>