diff options
author | Sarah German <sgerman@gitlab.com> | 2023-04-07 18:21:01 +0300 |
---|---|---|
committer | Sarah German <sgerman@gitlab.com> | 2023-04-07 18:21:01 +0300 |
commit | d5de2bd4f982cd40e4da45d3e47573f2b21e5cda (patch) | |
tree | 198df6999fb6dffcc87adb258f59469f74754b57 | |
parent | 3aaebe1805947604bab31d8826acd7a2b8659bc8 (diff) |
Adjust deprecation filter logic
4 files changed, 68 insertions, 56 deletions
diff --git a/content/assets/stylesheets/stylesheet.scss b/content/assets/stylesheets/stylesheet.scss index 28f0218b..3295f250 100644 --- a/content/assets/stylesheets/stylesheet.scss +++ b/content/assets/stylesheets/stylesheet.scss @@ -601,11 +601,19 @@ a.gl-tab-nav-item:hover { } } -select[name='removal_milestone'], -select[name='breaking'] { +.gl-form-select { background-image: $gl-icon-select-chevron-down; } +// Deprecations page +.deprecation-notes { + font-size: 0.9rem; + line-height: 1rem; +} +h2 .milestone-date { + font-size: 1.25rem; +} + // GitLab UI does not export vendor prefixes in the build we use, so we need to add them here. // Otherwise we don't get checkmarks in Chrome and Safari. // @see https://caniuse.com/css-masks diff --git a/content/frontend/deprecations/components/deprecation_filters.vue b/content/frontend/deprecations/components/deprecation_filters.vue index fb9042a2..ca27a1f8 100644 --- a/content/frontend/deprecations/components/deprecation_filters.vue +++ b/content/frontend/deprecations/components/deprecation_filters.vue @@ -7,21 +7,19 @@ export default { GlToggle, }, props: { - milestonesOptions: { + allMilestones: { type: Array, required: true, }, - showAllText: { - type: String, - required: true, - }, }, data() { return { emptyText: 'No deprecations found.', + showAllText: 'Show all', hiddenClass: 'gl-display-none', + milestoneOptions: [], selected: { - removal_milestone: this.showAllText, + removal_milestone: '', breaking_only: false, }, deprecations: [], @@ -35,6 +33,10 @@ export default { }, }, created() { + // Populate the milestones list + this.milestoneOptions = [this.showAllText].concat(this.allMilestones); + this.selected.removal_milestone = this.showAllText; + // Initialize with an array of all deprecations. document.querySelectorAll('.deprecation').forEach((el) => { this.deprecations.push(el.getAttribute('data-deprecation-id')); @@ -45,15 +47,20 @@ export default { if (searchParams.has('removal_milestone') || searchParams.has('breaking_only')) { this.selected.removal_milestone = searchParams.get('removal_milestone'); this.selected.breaking_only = searchParams.get('breaking_only') === 'true'; - this.filterList(); } + + this.filterList(); }, methods: { updateURLParams() { const url = new URL(window.location); + const filterDefaults = [this.showAllText, false]; + // Add the URL param if a value besides the default is selected. Object.keys(this.selected).forEach((selectName) => { - if (this.selected[selectName] !== this.showAllText) { + if (!filterDefaults.includes(this.selected[selectName])) { url.searchParams.set(selectName, this.selected[selectName]); + } else { + url.searchParams.delete(selectName); } }); window.history.pushState(null, '', url.toString()); @@ -61,9 +68,8 @@ export default { filterList() { // Run the deprecations list through both filters. this.selectedDeprecations = this.filterByBreaking(this.filterByVersion(this.deprecations)); - // Hide all headers initially. - document.querySelectorAll('.announcement-milestone').forEach((section) => { + document.querySelectorAll('.milestone-wrapper').forEach((section) => { section.children[0].classList.add(this.hiddenClass); }); @@ -85,10 +91,10 @@ export default { filterByVersion(deps) { let filteredDeps = deps; if (this.selected.removal_milestone !== this.showAllText) { - filteredDeps = deps.filter((depID) => - document - .querySelector(`[data-deprecation-id="${depID}"]`) - .classList.contains(`removal-${this.selected.removal_milestone}`), + filteredDeps = deps.filter( + (depID) => + document.querySelector(`[data-deprecation-id="${depID}"]`).dataset.milestone === + this.selected.removal_milestone, ); } return filteredDeps; @@ -121,7 +127,7 @@ export default { v-model="selected.removal_milestone" class="gl-md-max-w-15p gl-mr-6" name="removal_milestone" - :options="milestonesOptions" + :options="milestoneOptions" data-testid="removal-milestone-filter" @change="filterList()" /> diff --git a/content/frontend/deprecations/deprecations.js b/content/frontend/deprecations/deprecations.js index 3a651f67..3b2d8220 100644 --- a/content/frontend/deprecations/deprecations.js +++ b/content/frontend/deprecations/deprecations.js @@ -11,53 +11,52 @@ document.querySelectorAll('.deprecation').forEach((el, index) => { }); /** - * Builds an array of removal milestone options from page content. - * - * Each milestone object contains: - * - A text string, used for labels in the select options list. - * - A value string, which is the same as the text string, but without periods. - * This is used to match the query with CSS classes on deprecations. - * CSS classes cannot include periods, so we drop those for this element. - * - * @param {String} showAllText + * Builds an array of announcement milestone options from page content. * @return {Array} */ -const buildMilestonesList = (showAllText) => { - let milestones = []; - document.querySelectorAll('.removal-milestone').forEach((el) => { - if (!milestones.includes(el.innerText)) { - milestones.push(el.innerText); +const buildMilestonesList = () => { + const milestones = []; + document.querySelectorAll('[data-milestone]').forEach((el) => { + const { milestone } = el.dataset; + if (!milestones.includes(milestone)) { + milestones.push(milestone); } }); - milestones.sort(compareVersions).reverse(); - milestones = milestones.map((el) => { - return { value: el.replaceAll('.', ''), text: el }; - }); - milestones.unshift({ value: showAllText, text: showAllText }); - return milestones; + return milestones.sort(compareVersions).reverse(); }; document.addEventListener('DOMContentLoaded', async () => { + // Create the list of milestones from page content. + const allMilestones = buildMilestonesList(); + // Populate milestone dates. const releaseDates = await getReleaseDates(); - const dateFields = ['removal-date', 'support-end-date']; - - dateFields.forEach((field) => { - const depDates = document.querySelectorAll(`span.${field}`); - depDates.forEach((dd) => { - // Find the milestone value from within the sibling span tag. - // Use this to populate the date for the milestone. - const milestone = dd.parentNode.querySelector('.removal-milestone').innerText; - const releaseDate = Object.keys(releaseDates).find((key) => releaseDates[key] === milestone); - // eslint-disable-next-line no-param-reassign - dd.innerText = `(${releaseDate})`; + const getMilestoneDateHTML = (milestone) => { + const msDate = new Date( + Object.keys(releaseDates).find((key) => releaseDates[key] === milestone), + ); + const msFormattedDate = msDate.toLocaleString('default', { + month: 'short', + year: 'numeric', }); + return ` <span class="milestone-date">(${msFormattedDate})</span>`; + }; + // Add dates to removal milestone headings, before the anchor link. + document.querySelectorAll('.milestone-wrapper h2').forEach((el) => { + el.querySelector('a.anchor').insertAdjacentHTML( + 'beforebegin', + getMilestoneDateHTML(el.parentNode.dataset.milestone), + ); + }); + // Add dates to milestones in the notes section. + document.querySelectorAll('.deprecation-notes .milestone').forEach((dd) => { + dd.insertAdjacentHTML( + 'afterend', + getMilestoneDateHTML(dd.parentNode.querySelector('.milestone').innerText), + ); }); // Initialize the filters Vue component. - const showAllText = 'Show all'; - const milestonesOptions = buildMilestonesList(showAllText); - return new Vue({ el: '.js-deprecation-filters', components: { @@ -66,8 +65,7 @@ document.addEventListener('DOMContentLoaded', async () => { render(createElement) { return createElement(DeprecationFilters, { props: { - milestonesOptions, - showAllText, + allMilestones, }, }); }, diff --git a/spec/frontend/deprecations/deprecation_filters_spec.js b/spec/frontend/deprecations/deprecation_filters_spec.js index 5cf28357..34ce969c 100644 --- a/spec/frontend/deprecations/deprecation_filters_spec.js +++ b/spec/frontend/deprecations/deprecation_filters_spec.js @@ -5,14 +5,14 @@ import { mount } from '@vue/test-utils'; import DeprecationFilters from '../../../content/frontend/deprecations/components/deprecation_filters.vue'; -const propsData = { showAllText: 'Show all', milestonesOptions: [{ value: '160', text: '16.0' }] }; -const removalsFilterSelector = '[data-testid="removal-milestone-filter"]'; +const propsData = { allMilestones: ['17.0', '15.9', '15.8'] }; +const removalFilterSelector = '[data-testid="removal-milestone-filter"]'; const breakingFilterSelector = '[data-testid="breaking-filter"]'; describe('component: Deprecations Filter', () => { it('Filters are visible', () => { const wrapper = mount(DeprecationFilters, { propsData }); - expect(wrapper.find(removalsFilterSelector).isVisible()).toBe(true); + expect(wrapper.find(removalFilterSelector).isVisible()).toBe(true); expect(wrapper.find(breakingFilterSelector).isVisible()).toBe(true); }); }); |