diff options
author | David O'Regan <doregan@gitlab.com> | 2022-07-15 18:49:48 +0300 |
---|---|---|
committer | David O'Regan <doregan@gitlab.com> | 2022-07-15 18:49:48 +0300 |
commit | 885cfbbcb3d66dbf28836f2707f024bb3caa3d08 (patch) | |
tree | 16ddb2ed5dd3398d5cf2b562aa771f1d2f523ab9 | |
parent | d0d9e46b1785c67f3cbf55441595abc2b1310a3d (diff) | |
parent | b3c152da1c74e246ea0397680baac1e2ae0f1786 (diff) |
Merge branch '667-versions-menu' into 'main'
Make the versions dropdown dynamic
Closes #1101 and #667
See merge request gitlab-org/gitlab-docs!2808
-rw-r--r-- | content/assets/stylesheets/stylesheet.scss | 29 | ||||
-rw-r--r-- | content/frontend/default/components/versions_menu.vue | 80 | ||||
-rw-r--r-- | content/frontend/default/default.js | 17 | ||||
-rw-r--r-- | content/frontend/default/environment.js | 22 | ||||
-rw-r--r-- | content/frontend/services/fetch_versions.js | 8 | ||||
-rw-r--r-- | layouts/cta.html | 2 | ||||
-rw-r--r-- | layouts/header.html | 33 | ||||
-rw-r--r-- | layouts/home.html | 1 | ||||
-rw-r--r-- | package.json | 1 | ||||
-rw-r--r-- | spec/frontend/default/components/versions_menu_spec.js | 27 | ||||
-rw-r--r-- | yarn.lock | 5 |
11 files changed, 172 insertions, 53 deletions
diff --git a/content/assets/stylesheets/stylesheet.scss b/content/assets/stylesheets/stylesheet.scss index b7c988c0..5866f6b6 100644 --- a/content/assets/stylesheets/stylesheet.scss +++ b/content/assets/stylesheets/stylesheet.scss @@ -277,23 +277,8 @@ ol { font-size: 1rem; } - .btn { - line-height: 1rem; - font-size: 0.875rem; - } - .navbar-nav { margin-top: 0; - - .dropdown-menu { - a { - border-bottom: 0; - - &:hover { - border-bottom: 0; - } - } - } } /* Override Bootstrap theme color */ @@ -314,14 +299,14 @@ ol { color: $gds-indigo-100; } - .dropdown-toggle { + .gl-dropdown-toggle.gl-button.btn-default, + .gl-dropdown-toggle.gl-button.btn-default:hover, + .gl-dropdown-toggle.gl-button.btn-default:focus { background-color: $help-indigo-500; + color: $gds-white; + box-shadow: none; svg { - fill: $white; - margin-right: 0 !important; - } - &::after { - display: none; + fill: $gds-white; } } @@ -499,7 +484,7 @@ ol { } .btn-cta { - background-color: $header-free-trial-button-color; + background-color: $header-free-trial-button-color !important; } h2[id]::before, diff --git a/content/frontend/default/components/versions_menu.vue b/content/frontend/default/components/versions_menu.vue new file mode 100644 index 00000000..04d2b982 --- /dev/null +++ b/content/frontend/default/components/versions_menu.vue @@ -0,0 +1,80 @@ +<script> +import { GlDropdown, GlDropdownItem, GlDropdownDivider } from '@gitlab/ui'; +import { getVersions } from '../../services/fetch_versions'; +import { isGitLabHosted } from '../environment'; + +export default { + components: { + GlDropdown, + GlDropdownItem, + GlDropdownDivider, + }, + data() { + return { + versions: {}, + activeVersion: '', + }; + }, + async created() { + // Only build this menu if this is a GitLab-hosted copy of the site. + // Self-hosted Docs will only contain a single version. + if (isGitLabHosted()) { + try { + this.versions = await getVersions(); + this.activeVersion = this.getActiveVersion(this.versions); + } catch (err) { + console.error(`Failed to fetch versions.json: ${err}`); // eslint-disable-line no-console + } + } + }, + methods: { + getVersionPath(versionNumber) { + let path = window.location.pathname; + if (versionNumber) { + path = `/${versionNumber}${path}`; + } + return path; + }, + getActiveVersion(versions) { + let activeVersion = versions.next; + + // Check if the first item in the URL path is a valid version. + // If so, that should be the active menu item. + const versionPath = window.location.pathname.split('/')[1]; + if (Object.values(this.versions).includes(versionPath)) { + activeVersion = versionPath; + } + return activeVersion; + }, + }, +}; +</script> + +<template> + <gl-dropdown + v-if="versions.next" + :text="activeVersion" + class="gl-mb-4 gl-md-mb-0 gl-md-mr-5 gl-md-ml-3 gl-display-flex" + data-testid="versions-menu" + > + <gl-dropdown-item :href="getVersionPath()"> + <span data-testid="next-version">{{ versions.next }}</span> (not yet released) + </gl-dropdown-item> + <gl-dropdown-divider /> + + <gl-dropdown-item :href="getVersionPath(versions.current)"> + {{ versions.current }} (recently released) + </gl-dropdown-item> + <gl-dropdown-item v-for="v in versions.last_minor" :key="v" :href="getVersionPath(v)"> + {{ v }} + </gl-dropdown-item> + <gl-dropdown-divider /> + + <gl-dropdown-item v-for="v in versions.last_major" :key="v" :href="getVersionPath(v)"> + {{ v }} + </gl-dropdown-item> + <gl-dropdown-divider /> + + <gl-dropdown-item href="/archives">Archives</gl-dropdown-item> + </gl-dropdown> +</template> diff --git a/content/frontend/default/default.js b/content/frontend/default/default.js index db3786f2..119842e8 100644 --- a/content/frontend/default/default.js +++ b/content/frontend/default/default.js @@ -2,6 +2,7 @@ import Vue from 'vue'; import NavigationToggle from './components/navigation_toggle.vue'; import VersionBanner from './components/version_banner.vue'; import { setupTableOfContents } from './setup_table_of_contents'; +import VersionsMenu from './components/versions_menu.vue'; function fixScrollPosition() { if (!window.location.hash || !document.querySelector(window.location.hash)) return; @@ -17,6 +18,10 @@ function fixScrollPosition() { document.addEventListener('DOMContentLoaded', () => { const versionBanner = document.querySelector('#js-version-banner'); + if (!versionBanner) { + return; + } + const isOutdated = versionBanner.hasAttribute('data-is-outdated'); const { latestVersionUrl, archivesUrl } = versionBanner.dataset; @@ -58,3 +63,15 @@ document.addEventListener('DOMContentLoaded', () => { setupTableOfContents(); }); + +document.addEventListener('DOMContentLoaded', () => { + return new Vue({ + el: '.js-versions-menu', + components: { + VersionsMenu, + }, + render(createElement) { + return createElement(VersionsMenu); + }, + }); +}); diff --git a/content/frontend/default/environment.js b/content/frontend/default/environment.js new file mode 100644 index 00000000..05e8ced5 --- /dev/null +++ b/content/frontend/default/environment.js @@ -0,0 +1,22 @@ +/** + * Utilities for determining site environment. + */ + +export const GlHosts = [ + { + environment: 'production', + host: 'docs.gitlab.com', + }, + { + environment: 'review', + host: '35.193.151.162.nip.io', + }, + { + environment: 'local', + host: 'localhost', + }, +]; + +export function isGitLabHosted() { + return GlHosts.some((e) => window.location.host.includes(e.host)); +} diff --git a/content/frontend/services/fetch_versions.js b/content/frontend/services/fetch_versions.js new file mode 100644 index 00000000..e65f396c --- /dev/null +++ b/content/frontend/services/fetch_versions.js @@ -0,0 +1,8 @@ +export function getVersions() { + return fetch('https://docs.gitlab.com/versions.json') + .then((response) => response.json()) + .then((data) => { + return data[0]; + }) + .catch((error) => console.error(error)); // eslint-disable-line no-console +} diff --git a/layouts/cta.html b/layouts/cta.html index 885378b6..29d6a920 100644 --- a/layouts/cta.html +++ b/layouts/cta.html @@ -1,3 +1,3 @@ -<a class="btn btn-danger btn-cta text-white" href="https://about.gitlab.com/free-trial/?glm_source=docs.gitlab.com&glm_content=navigation-cta-docs" target="_blank" rel="noopener noreferrer" role="button"> +<a class="gl-button btn btn-cta text-white gl-shadow-none! gl-md-pr-3" href="https://about.gitlab.com/free-trial/?glm_source=docs.gitlab.com&glm_content=navigation-cta-docs" target="_blank" rel="noopener noreferrer" role="button"> Get free trial </a> diff --git a/layouts/header.html b/layouts/header.html index f77ff133..e521a008 100644 --- a/layouts/header.html +++ b/layouts/header.html @@ -22,36 +22,9 @@ <a class="nav-link" href="https://about.gitlab.com/releases/categories/releases/" target="_blank">What's new?</a> </li> </ul> - <ul class="navbar-nav mb-0"> - <li class="nav-item p-2 dropdown"> - <button class="btn dropdown-toggle text-white" type="button" id="navbarDropdown" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> - <%= version_dropdown_title %><%= icon('chevron-down') %> - </button> - <div class="dropdown-menu" aria-labelledby="navbarDropdown"> - <a class="dropdown-item" <%= active_dropdown(ENV['CI_DEFAULT_BRANCH']) %> href='<%= @item.identifier.without_ext + '.html' %>' class="versions-tooltip"><%= dotcom %> - <i class="fa fa-question-circle-o" aria-hidden="true" data-toggle="tooltip" data-placement="bottom" title="Latest pre-release version of GitLab, with features available or about to become available on GitLab.com. For self-managed GitLab installations, select your version number as listed at your GitLab instance's /help URL."></i> - </a> - <% if display_previous_versions? %> - <!-- Start of online versions --> - <div class="dropdown-divider"></div> - <% data_versions[:online].each do |version| %> - <%= render '/partials/versions_list.*', version: version %> - <% end %> - <!-- End of online versions --> - - <!-- Start of last major versions --> - <div class="dropdown-divider"></div> - <% data_versions[:previous_majors].each do |version| %> - <%= render '/partials/versions_list.*', version: version %> - <% end %> - <!-- End of last major versions --> - - <% end %> - <div class="dropdown-divider"></div> - <a class="dropdown-item" <%= active_dropdown('archives') %> href='/archives/'>Archives</a> - </div> - </li> - <li class="nav-item p-2"> + <div class="js-versions-menu"></div> + <ul class="navbar-nav gl-mb-3 gl-md-mb-0 gl-md-pr-3"> + <li class="nav-item"> <% if @item.identifier.to_s.split('/')[1] == 'omnibus' %> <%= render '/cta_omnibus.*' %> <% else %> diff --git a/layouts/home.html b/layouts/home.html index 6c5bb728..3b79e055 100644 --- a/layouts/home.html +++ b/layouts/home.html @@ -15,6 +15,7 @@ <%= render '/schema-microdata.*' %> <script src="<%= @items['/frontend/header/index.*'].path %>"></script> <script src="<%= @items['/frontend/shared/global_imports.*'].path %>"></script> + <script src="<%= @items['/frontend/default/default.*'].path %>"></script> <script src="<%= @items['/frontend/search/docsearch.*'].path %>"></script> <script src="<%= @items['/assets/javascripts/badges.*'].path %>"></script> </body> diff --git a/package.json b/package.json index 71796764..93537f32 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "@vue/vue2-jest": "^28.0.1", "babel-jest": "^28.1.2", "eslint": "^8.19.0", + "flush-promises": "^1.0.2", "glob": "^8.0.3", "jest": "^28.1.2", "jest-environment-jsdom": "^28.1.2", diff --git a/spec/frontend/default/components/versions_menu_spec.js b/spec/frontend/default/components/versions_menu_spec.js new file mode 100644 index 00000000..e7cadd20 --- /dev/null +++ b/spec/frontend/default/components/versions_menu_spec.js @@ -0,0 +1,27 @@ +/** + * @jest-environment jsdom + */ + +import { mount } from '@vue/test-utils'; +import flushPromises from 'flush-promises'; +import VersionsMenu from '../../../../content/frontend/default/components/versions_menu.vue'; +import { getVersions } from '../../../../content/frontend/services/fetch_versions'; + +jest.mock('../../../../content/frontend/services/fetch_versions'); +beforeEach(() => { + jest.clearAllMocks(); +}); + +describe('component: Versions menu', () => { + it('Fetches versions.json and displays current version', async () => { + const mockNextVersion = '15.2'; + getVersions.mockResolvedValueOnce({ next: mockNextVersion }); + const wrapper = mount(VersionsMenu); + + await flushPromises(); + expect(getVersions).toHaveBeenCalledTimes(1); + + const nextVersion = wrapper.find('[data-testid="next-version"]').element.textContent; + expect(nextVersion).toEqual(mockNextVersion); + }); +}); @@ -3829,6 +3829,11 @@ flatted@^3.1.0: resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.6.tgz#022e9218c637f9f3fc9c35ab9c9193f05add60b2" integrity sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ== +flush-promises@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/flush-promises/-/flush-promises-1.0.2.tgz#4948fd58f15281fed79cbafc86293d5bb09b2ced" + integrity sha512-G0sYfLQERwKz4+4iOZYQEZVpOt9zQrlItIxQAAYAWpfby3gbHrx0osCHz5RLl/XoXevXk0xoN4hDFky/VV9TrA== + form-data@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" |