Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-docs.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSarah German <sgerman@gitlab.com>2023-04-07 18:21:01 +0300
committerSarah German <sgerman@gitlab.com>2023-04-07 18:21:01 +0300
commitd5de2bd4f982cd40e4da45d3e47573f2b21e5cda (patch)
tree198df6999fb6dffcc87adb258f59469f74754b57
parent3aaebe1805947604bab31d8826acd7a2b8659bc8 (diff)
Adjust deprecation filter logic
-rw-r--r--content/assets/stylesheets/stylesheet.scss12
-rw-r--r--content/frontend/deprecations/components/deprecation_filters.vue36
-rw-r--r--content/frontend/deprecations/deprecations.js70
-rw-r--r--spec/frontend/deprecations/deprecation_filters_spec.js6
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 `&nbsp;<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);
});
});