diff options
author | Sarah German <sgerman@gitlab.com> | 2023-04-15 00:05:17 +0300 |
---|---|---|
committer | Sarah German <sgerman@gitlab.com> | 2023-05-01 20:41:08 +0300 |
commit | 35d9df42398c622fdd2be24e82ddcbf31dcdda57 (patch) | |
tree | 5a75c2e9db5315ce81b91b56283a0fbef7b62e18 | |
parent | 4247577e7114b66b3b5764f7d1613ebfca35baae (diff) |
Refactor the archived version banner1515-banner-refactor
-rw-r--r-- | content/frontend/default/components/version_banner.vue | 79 | ||||
-rw-r--r-- | content/frontend/default/default.js | 15 | ||||
-rw-r--r-- | content/frontend/services/fetch_versions.js | 9 | ||||
-rw-r--r-- | content/frontend/shared/components/docs_banner.vue | 50 | ||||
-rw-r--r-- | layouts/default.html | 6 | ||||
-rw-r--r-- | lib/helpers/versions.rb | 28 | ||||
-rw-r--r-- | spec/frontend/default/components/helpers/versions_helper.js (renamed from spec/frontend/default/components/helpers/versions_menu_helper.js) | 15 | ||||
-rw-r--r-- | spec/frontend/default/components/versions_spec.js (renamed from spec/frontend/default/components/versions_menu_spec.js) | 37 | ||||
-rw-r--r-- | spec/frontend/shared/components/docs_banner_spec.js | 39 | ||||
-rw-r--r-- | spec/lib/helpers/versions_spec.rb | 39 |
10 files changed, 120 insertions, 197 deletions
diff --git a/content/frontend/default/components/version_banner.vue b/content/frontend/default/components/version_banner.vue index 22004a95..e1ae6a73 100644 --- a/content/frontend/default/components/version_banner.vue +++ b/content/frontend/default/components/version_banner.vue @@ -1,35 +1,74 @@ <script> -import DocsBanner from '../../shared/components/docs_banner.vue'; +import { GlAlert } from '@gitlab/ui'; +import { getVersions } from '../../services/fetch_versions'; +import { isArchivesSite } from '../environment'; export default { components: { - DocsBanner, + GlAlert, }, - props: { - isOutdated: { - type: Boolean, - required: true, - }, - latestVersionUrl: { - type: String, - required: true, - }, - archivesUrl: { - type: String, - required: true, + data() { + return { + versions: {}, + }; + }, + computed: { + latestPath() { + return `https://docs.gitlab.com${window.location.pathname}`; }, }, + async created() { + this.versions = await getVersions(); + if (this.isArchivedVersion()) { + document.body.classList.add('has-banner'); + } + }, methods: { - toggleVersionBanner(isVisible) { - this.$emit('toggleVersionBanner', isVisible); + isArchivedVersion() { + const version = document.querySelector('meta[name="gitlab-docs-version"]').content; + if (isArchivesSite() || ![this.versions.next, this.versions.current].includes(version)) { + return true; + } + return false; }, }, }; </script> <template> - <docs-banner :show="isOutdated" @toggle="toggleVersionBanner"> - This is <a :href="archivesUrl">archived documentation</a> for GitLab. Go to - <a :href="latestVersionUrl">the latest</a>. - </docs-banner> + <gl-alert + v-if="isArchivedVersion()" + sticky + :show-icon="false" + :dismissible="false" + variant="tip" + class="gl-text-center gl-z-index-200" + data-testid="version-banner" + > + This is archived documentation for GitLab. Go to + <a :href="latestPath">the latest</a>. + </gl-alert> </template> + +<style> +.has-banner { + overscroll-behavior: none; +} +.has-banner .nav-wrapper { + top: 2rem; +} +.has-banner .nav-wrapper .nav-toggle { + position: relative; + top: -2rem; +} +.gl-alert { + top: 3rem; + padding: 0.5rem 3rem; +} +.gl-alert a { + color: #5943b6; +} +.has-banner section.gl-docs { + margin-top: 1rem; +} +</style> diff --git a/content/frontend/default/default.js b/content/frontend/default/default.js index 10a82fb7..bd552caf 100644 --- a/content/frontend/default/default.js +++ b/content/frontend/default/default.js @@ -30,26 +30,15 @@ document.addEventListener('DOMContentLoaded', () => { /** * Banner components */ - const versionBanner = document.querySelector('#js-version-banner'); + const versionBanner = document.querySelector('[data-version-banner]'); if (versionBanner) { - const isOutdated = versionBanner.hasAttribute('data-is-outdated'); - const { latestVersionUrl, archivesUrl } = versionBanner.dataset; - new Vue({ el: versionBanner, components: { VersionBanner, }, render(createElement) { - return createElement(VersionBanner, { - props: { isOutdated, latestVersionUrl, archivesUrl }, - on: { - toggleVersionBanner(isVisible) { - const wrapper = document.querySelector('.wrapper'); - wrapper.classList.toggle('show-banner', isVisible); - }, - }, - }); + return createElement(VersionBanner); }, }); } diff --git a/content/frontend/services/fetch_versions.js b/content/frontend/services/fetch_versions.js index 6edf3e45..33da1f0e 100644 --- a/content/frontend/services/fetch_versions.js +++ b/content/frontend/services/fetch_versions.js @@ -14,12 +14,19 @@ const DOCS_IMAGES_ENDPOINT = * @returns Array */ export function getVersions() { - return fetch(DOCS_VERSIONS_ENDPOINT) + if (window.onlineVersions) { + return window.onlineVersions; + } + const onlineVersions = fetch(DOCS_VERSIONS_ENDPOINT) .then((response) => response.json()) .then((data) => { return Object.assign(...data); }) .catch((error) => console.error(error)); + + // Save this as a global to avoid repeated HTTP requests. + window.onlineVersions = onlineVersions; + return onlineVersions; } /** diff --git a/content/frontend/shared/components/docs_banner.vue b/content/frontend/shared/components/docs_banner.vue deleted file mode 100644 index 0c205a05..00000000 --- a/content/frontend/shared/components/docs_banner.vue +++ /dev/null @@ -1,50 +0,0 @@ -<script> -import { GlButton } from '@gitlab/ui'; - -export default { - components: { - GlButton, - }, - props: { - text: { - type: String, - required: false, - default: '', - }, - show: { - type: Boolean, - required: false, - default: true, - }, - }, - data() { - return { - isVisible: this.show, - }; - }, - mounted() { - this.toggleBanner(this.isVisible); - }, - methods: { - toggleBanner(isVisible) { - this.$emit('toggle', isVisible); - this.isVisible = isVisible; - }, - }, -}; -</script> - -<template> - <div - v-if="isVisible" - class="gl-z-index-3 gl-left-0 gl-bg-gray-50 gl-border-b-gray-200 gl-fixed gl-w-full gl-text-center" - > - <span v-if="text">{{ text }}</span> - <slot></slot> - <gl-button - icon="close" - class="gl-shadow-none! gl-bg-transparent!" - @click="toggleBanner(false)" - /> - </div> -</template> diff --git a/layouts/default.html b/layouts/default.html index 5a99862d..4f447e36 100644 --- a/layouts/default.html +++ b/layouts/default.html @@ -8,6 +8,7 @@ <body itemscope itemtype="http://schema.org/WebPage" data-spy="scroll" data-target="#doc-nav" data-offset="90"> <%= render '/gtm.*' %> <%= render '/header.*' %> + <div data-version-banner class="version-banner"></div> <section class="gl-docs container-fluid gl-mt-9"> <div class="row"> <div class="col-0 col-xl-2 pl-0"> @@ -24,11 +25,6 @@ <div class="main pl-xl-4 wrapper js-main-wrapper col-12 col-xl-7"> <div class="row"> <div class="col"> - <div id="js-version-banner" <%= 'data-is-outdated' if show_version_banner? %> data-latest-version-url='<%= @item.identifier.without_ext + '.html' %>' data-archives-url="/archives/"></div> - </div> - </div> - <div class="row"> - <div class="col"> <%= render '/banner.*' %> </div> </div> diff --git a/lib/helpers/versions.rb b/lib/helpers/versions.rb index c34e38ac..d21e68a9 100644 --- a/lib/helpers/versions.rb +++ b/lib/helpers/versions.rb @@ -5,16 +5,6 @@ module Nanoc::Helpers STABLE_VERSIONS_REGEX = %r{^\d{1,2}\.\d{1,2}$}.freeze # - # Determines whether or not to display the version banner on the frontend. - # - # Note: We only want the banner to display on production. - # Production is the only environment where we serve multiple versions. - # - def show_version_banner? - production? && !latest? - end - - # # Returns the site version using the branch or tag from the CI build. # def site_version @@ -42,24 +32,6 @@ module Nanoc::Helpers end # - # Returns the current stable version. - # - def get_current_stable_version - config[:online_versions][:current] - end - - # - # Check if this site version is the latest. - # - # We consider two versions to be "latest": - # 1) The main branch (CI_DEFAULT_BRANCH), which are pre-release docs for the next version. - # 2) The most recent stable release, which is "current" in versions.json. - # - def latest? - ENV['CI_COMMIT_REF_NAME'] == ENV['CI_DEFAULT_BRANCH'] || ENV['CI_COMMIT_REF_NAME'] == get_current_stable_version - end - - # # Stable versions regexp # # At most two digits for major and minor numbers. diff --git a/spec/frontend/default/components/helpers/versions_menu_helper.js b/spec/frontend/default/components/helpers/versions_helper.js index 5842880e..3a4f6796 100644 --- a/spec/frontend/default/components/helpers/versions_menu_helper.js +++ b/spec/frontend/default/components/helpers/versions_helper.js @@ -14,6 +14,21 @@ export const setWindowPath = (pathname) => { }; /** + * Creates a mock browser window object with a given hostname. + * @param {String} hostname + */ +export const setWindowHostname = (hostname) => { + const location = { + ...window.location, + hostname, + }; + Object.defineProperty(window, 'location', { + writable: true, + value: location, + }); +}; + +/** * Creates a mock gitlab-docs-version metatag. * @param {String} pathname */ diff --git a/spec/frontend/default/components/versions_menu_spec.js b/spec/frontend/default/components/versions_spec.js index 7de730d2..6872e288 100644 --- a/spec/frontend/default/components/versions_menu_spec.js +++ b/spec/frontend/default/components/versions_spec.js @@ -2,12 +2,13 @@ * @jest-environment jsdom */ -import { mount } from '@vue/test-utils'; +import { mount, shallowMount } from '@vue/test-utils'; import flushPromises from 'flush-promises'; import VersionsMenu from '../../../../content/frontend/default/components/versions_menu.vue'; +import VersionBanner from '../../../../content/frontend/default/components/version_banner.vue'; import { getVersions } from '../../../../content/frontend/services/fetch_versions'; import { mockVersions } from '../../__mocks__/versions_mock'; -import { setWindowPath, setVersionMetatag } from './helpers/versions_menu_helper'; +import { setWindowPath, setWindowHostname, setVersionMetatag } from './helpers/versions_helper'; jest.mock('../../../../content/frontend/services/fetch_versions'); @@ -89,3 +90,35 @@ describe('component: Versions menu', () => { expect(wrapper.find('[data-testid="versions-menu"] a:nth-child(2)').exists()).toBe(false); }); }); + +describe('component: Versions banner', () => { + it('Shows the banner for a version on archives.docs.gitlab.com', async () => { + setWindowHostname('archives.docs.gitlab.com'); + setVersionMetatag('15.8'); + const wrapper = shallowMount(VersionBanner); + await wrapper.setData({ versions: mockVersions }); + expect(wrapper.find('[data-testid="version-banner"]').exists()).toBe(true); + }); + + it('Shows the banner for an archive version on docs.gitlab.com', async () => { + setWindowHostname('docs.gitlab.com'); + setVersionMetatag(mockVersions.last_major[0]); + const wrapper = shallowMount(VersionBanner); + await wrapper.setData({ versions: mockVersions }); + expect(wrapper.find('[data-testid="version-banner"]').exists()).toBe(true); + }); + + it('Does not show the banner for the latest version', async () => { + setVersionMetatag(mockVersions.next); + const wrapper = shallowMount(VersionBanner); + await wrapper.setData({ versions: mockVersions }); + expect(wrapper.find('[data-testid="version-banner"]').exists()).toBe(false); + }); + + it('Does not show the banner for the stable version', async () => { + setVersionMetatag(mockVersions.current); + const wrapper = shallowMount(VersionBanner); + await wrapper.setData({ versions: mockVersions }); + expect(wrapper.find('[data-testid="version-banner"]').exists()).toBe(false); + }); +}); diff --git a/spec/frontend/shared/components/docs_banner_spec.js b/spec/frontend/shared/components/docs_banner_spec.js deleted file mode 100644 index aabb623d..00000000 --- a/spec/frontend/shared/components/docs_banner_spec.js +++ /dev/null @@ -1,39 +0,0 @@ -/** - * @jest-environment jsdom - */ - -import { mount } from '@vue/test-utils'; -import DocsBanner from '../../../../content/frontend/shared/components/docs_banner.vue'; - -const propsData = { text: 'Some text', show: true }; - -describe('component: Banner', () => { - let wrapper; - - beforeEach(() => { - wrapper = mount(DocsBanner, { propsData }); - }); - - it('renders a banner', () => { - expect(wrapper.exists('.banner')).toBe(true); - }); - - it('renders the correct banner text', () => { - const bannerText = wrapper.find('span'); - expect(bannerText.text()).toEqual(propsData.text); - }); - - it('renders a close button', () => { - expect(wrapper.exists('[data-testid="close-icon"]')).toBe(true); - }); - - it('emits a toggle event on mount', () => { - expect(wrapper.emitted('toggle')[0]).toEqual([true]); - }); - - it('emits a toggle event when the close button is clicked', () => { - const closeBtn = wrapper.find('[data-testid="close-icon"]'); - closeBtn.trigger('click'); - expect(wrapper.emitted('toggle')[1]).toEqual([false]); - }); -}); diff --git a/spec/lib/helpers/versions_spec.rb b/spec/lib/helpers/versions_spec.rb deleted file mode 100644 index 2c7e61cb..00000000 --- a/spec/lib/helpers/versions_spec.rb +++ /dev/null @@ -1,39 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require 'nanoc' -require 'helpers/versions' - -RSpec.describe Nanoc::Helpers::VersionsDropdown do - let(:mock_class) { Class.new { extend Nanoc::Helpers::VersionsDropdown } } - - subject { mock_class.latest? } - - describe '#latest?' do - before do - versions_mock = { next: "15.8", current: "15.7", last_minor: ["15.6", "15.5"], last_major: ["14.10", "13.12"] } - allow(mock_class).to receive(:get_current_stable_version).and_return(versions_mock[:current]) - stub_const('ENV', ENV.to_hash.merge('CI_DEFAULT_BRANCH' => 'main')) - end - - it 'returns correct value for pre-release version' do - stub_const('ENV', ENV.to_hash.merge('CI_COMMIT_REF_NAME' => 'main')) - expect(subject).to be(true) - end - - it 'returns correct value for current stable version' do - stub_const('ENV', ENV.to_hash.merge('CI_COMMIT_REF_NAME' => '15.7')) - expect(subject).to be(true) - end - - it 'returns correct value for last minor version' do - stub_const('ENV', ENV.to_hash.merge('CI_COMMIT_REF_NAME' => '15.6')) - expect(subject).to be(false) - end - - it 'returns correct value for last major' do - stub_const('ENV', ENV.to_hash.merge('CI_COMMIT_REF_NAME' => '14.10')) - expect(subject).to be(false) - end - end -end |