diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-02-02 18:09:42 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-02-02 18:09:42 +0000 |
commit | 2d66c59d593354aa98785899cc8d5e640f62a012 (patch) | |
tree | b0f82a38ffba401a1ad448983785660038c4cf4b /app/assets | |
parent | dab865db1e85e2fc3dd29dae8dc6b8e11b1ba3f7 (diff) | |
download | gitlab-ce-2d66c59d593354aa98785899cc8d5e640f62a012.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets')
11 files changed, 259 insertions, 34 deletions
diff --git a/app/assets/javascripts/ci_variable_list/components/ci_variable_popover.vue b/app/assets/javascripts/ci_variable_list/components/ci_variable_popover.vue index 431819124c2..6e6527df63f 100644 --- a/app/assets/javascripts/ci_variable_list/components/ci_variable_popover.vue +++ b/app/assets/javascripts/ci_variable_list/components/ci_variable_popover.vue @@ -38,7 +38,9 @@ export default { <template> <div id="popover-container"> <gl-popover :target="target" triggers="hover" placement="top" container="popover-container"> - <div class="gl-display-flex gl-justify-content-space-between gl-align-items-center"> + <div + class="gl-display-flex gl-justify-content-space-between gl-align-items-center gl-word-break-all" + > <div class="ci-popover-value gl-pr-3"> {{ displayValue }} </div> diff --git a/app/assets/javascripts/deploy_keys/components/key.vue b/app/assets/javascripts/deploy_keys/components/key.vue index 3ddaba7abcc..797f5a6aaf0 100644 --- a/app/assets/javascripts/deploy_keys/components/key.vue +++ b/app/assets/javascripts/deploy_keys/components/key.vue @@ -97,7 +97,7 @@ export default { methods: { projectTooltipTitle(project) { return project.can_push - ? s__('DeployKeys|Write access allowed') + ? s__('DeployKeys|Grant write permissions to this key') : s__('DeployKeys|Read access only'); }, toggleExpanded() { diff --git a/app/assets/javascripts/lib/utils/datetime_utility.js b/app/assets/javascripts/lib/utils/datetime_utility.js index d290c747ad6..6622cc42c2b 100644 --- a/app/assets/javascripts/lib/utils/datetime_utility.js +++ b/app/assets/javascripts/lib/utils/datetime_utility.js @@ -676,69 +676,127 @@ export const secondsToHours = (offset) => { }; /** - * Returns the date n days after the date provided + * Returns the date `n` days after the date provided * * @param {Date} date the initial date * @param {Number} numberOfDays number of days after - * @return {Date} the date following the date provided + * @param {Object} [options={}] Additional options for this calculation + * @param {boolean} [options.utc=false] Perform the calculation using UTC dates. + * This will cause Daylight Saving Time to be ignored. Defaults to `false` + * if not provided, which causes the calculation to be performed in the + * user's timezone. + * + * @return {Date} A `Date` object `n` days after the provided `Date` */ -export const nDaysAfter = (date, numberOfDays) => - new Date(newDate(date)).setDate(date.getDate() + numberOfDays); +export const nDaysAfter = (date, numberOfDays, { utc = false } = {}) => { + const clone = newDate(date); + + const cloneValue = utc + ? clone.setUTCDate(date.getUTCDate() + numberOfDays) + : clone.setDate(date.getDate() + numberOfDays); + + return new Date(cloneValue); +}; /** - * Returns the date n days before the date provided + * Returns the date `n` days before the date provided * * @param {Date} date the initial date * @param {Number} numberOfDays number of days before - * @return {Date} the date preceding the date provided + * @param {Object} [options={}] Additional options for this calculation + * @param {boolean} [options.utc=false] Perform the calculation using UTC dates. + * This will cause Daylight Saving Time to be ignored. Defaults to `false` + * if not provided, which causes the calculation to be performed in the + * user's timezone. + * @return {Date} A `Date` object `n` days before the provided `Date` */ -export const nDaysBefore = (date, numberOfDays) => nDaysAfter(date, -numberOfDays); +export const nDaysBefore = (date, numberOfDays, options) => + nDaysAfter(date, -numberOfDays, options); /** - * Returns the date n weeks after the date provided + * Returns the date `n` weeks after the date provided * * @param {Date} date the initial date * @param {Number} numberOfWeeks number of weeks after - * @return {Date} the date following the date provided + * @param {Object} [options={}] Additional options for this calculation + * @param {boolean} [options.utc=false] Perform the calculation using UTC dates. + * This will cause Daylight Saving Time to be ignored. Defaults to `false` + * if not provided, which causes the calculation to be performed in the + * user's timezone. + * + * @return {Date} A `Date` object `n` weeks after the provided `Date` */ -export const nWeeksAfter = (date, numberOfWeeks) => - new Date(newDate(date)).setDate(date.getDate() + DAYS_IN_WEEK * numberOfWeeks); +export const nWeeksAfter = (date, numberOfWeeks, options) => + nDaysAfter(date, DAYS_IN_WEEK * numberOfWeeks, options); /** - * Returns the date n weeks before the date provided + * Returns the date `n` weeks before the date provided * * @param {Date} date the initial date * @param {Number} numberOfWeeks number of weeks before - * @return {Date} the date following the date provided + * @param {Object} [options={}] Additional options for this calculation + * @param {boolean} [options.utc=false] Perform the calculation using UTC dates. + * This will cause Daylight Saving Time to be ignored. Defaults to `false` + * if not provided, which causes the calculation to be performed in the + * user's timezone. + * + * @return {Date} A `Date` object `n` weeks before the provided `Date` */ -export const nWeeksBefore = (date, numberOfWeeks) => nWeeksAfter(date, -numberOfWeeks); +export const nWeeksBefore = (date, numberOfWeeks, options) => + nWeeksAfter(date, -numberOfWeeks, options); /** - * Returns the date n months after the date provided + * Returns the date `n` months after the date provided * * @param {Date} date the initial date * @param {Number} numberOfMonths number of months after - * @return {Date} the date following the date provided + * @param {Object} [options={}] Additional options for this calculation + * @param {boolean} [options.utc=false] Perform the calculation using UTC dates. + * This will cause Daylight Saving Time to be ignored. Defaults to `false` + * if not provided, which causes the calculation to be performed in the + * user's timezone. + * + * @return {Date} A `Date` object `n` months after the provided `Date` */ -export const nMonthsAfter = (date, numberOfMonths) => - new Date(newDate(date)).setMonth(date.getMonth() + numberOfMonths); +export const nMonthsAfter = (date, numberOfMonths, { utc = false } = {}) => { + const clone = newDate(date); + + const cloneValue = utc + ? clone.setUTCMonth(date.getUTCMonth() + numberOfMonths) + : clone.setMonth(date.getMonth() + numberOfMonths); + + return new Date(cloneValue); +}; /** - * Returns the date n months before the date provided + * Returns the date `n` months before the date provided * * @param {Date} date the initial date * @param {Number} numberOfMonths number of months before - * @return {Date} the date preceding the date provided + * @param {Object} [options={}] Additional options for this calculation + * @param {boolean} [options.utc=false] Perform the calculation using UTC dates. + * This will cause Daylight Saving Time to be ignored. Defaults to `false` + * if not provided, which causes the calculation to be performed in the + * user's timezone. + * + * @return {Date} A `Date` object `n` months before the provided `Date` */ -export const nMonthsBefore = (date, numberOfMonths) => nMonthsAfter(date, -numberOfMonths); +export const nMonthsBefore = (date, numberOfMonths, options) => + nMonthsAfter(date, -numberOfMonths, options); /** * Returns the date after the date provided * * @param {Date} date the initial date + * @param {Object} [options={}] Additional options for this calculation + * @param {boolean} [options.utc=false] Perform the calculation using UTC dates. + * This will cause Daylight Saving Time to be ignored. Defaults to `false` + * if not provided, which causes the calculation to be performed in the + * user's timezone. + * * @return {Date} the date following the date provided */ -export const dayAfter = (date) => new Date(newDate(date).setDate(date.getDate() + 1)); +export const dayAfter = (date, options) => nDaysAfter(date, 1, options); /** * Mimics the behaviour of the rails distance_of_time_in_words function @@ -933,3 +991,22 @@ export const isToday = (date) => { date.getFullYear() === today.getFullYear() ); }; + +/** + * Returns the start of the provided day + * + * @param {Object} [options={}] Additional options for this calculation + * @param {boolean} [options.utc=false] Perform the calculation using UTC time. + * If `true`, the time returned will be midnight UTC. If `false` (the default) + * the time returned will be midnight in the user's local time. + * + * @returns {Date} A new `Date` object that represents the start of the day + * of the provided date + */ +export const getStartOfDay = (date, { utc = false } = {}) => { + const clone = newDate(date); + + const cloneValue = utc ? clone.setUTCHours(0, 0, 0, 0) : clone.setHours(0, 0, 0, 0); + + return new Date(cloneValue); +}; diff --git a/app/assets/javascripts/pages/admin/runners/index.js b/app/assets/javascripts/pages/admin/runners/index.js index 1b373226664..0b92f5ef90f 100644 --- a/app/assets/javascripts/pages/admin/runners/index.js +++ b/app/assets/javascripts/pages/admin/runners/index.js @@ -10,7 +10,5 @@ document.addEventListener('DOMContentLoaded', () => { useDefaultState: true, }); - if (gon?.features?.runnerInstructions) { - initInstallRunner(); - } + initInstallRunner(); }); diff --git a/app/assets/javascripts/pages/groups/settings/ci_cd/show/index.js b/app/assets/javascripts/pages/groups/settings/ci_cd/show/index.js index 3ce779975f7..19d81f61dba 100644 --- a/app/assets/javascripts/pages/groups/settings/ci_cd/show/index.js +++ b/app/assets/javascripts/pages/groups/settings/ci_cd/show/index.js @@ -20,7 +20,5 @@ document.addEventListener('DOMContentLoaded', () => { initSharedRunnersForm(); initVariableList(); - if (gon?.features?.runnerInstructions) { - initInstallRunner(); - } + initInstallRunner(); }); diff --git a/app/assets/javascripts/pages/projects/settings/ci_cd/show/index.js b/app/assets/javascripts/pages/projects/settings/ci_cd/show/index.js index 0eb40ff30f9..f2dd0da4d62 100644 --- a/app/assets/javascripts/pages/projects/settings/ci_cd/show/index.js +++ b/app/assets/javascripts/pages/projects/settings/ci_cd/show/index.js @@ -41,7 +41,5 @@ document.addEventListener('DOMContentLoaded', () => { initSharedRunnersToggle(); } - if (gon?.features?.runnerInstructions) { - initInstallRunner(); - } + initInstallRunner(); }); diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/stage.vue b/app/assets/javascripts/pipelines/components/pipelines_list/stage.vue index a9154d93194..37d73a75c67 100644 --- a/app/assets/javascripts/pipelines/components/pipelines_list/stage.vue +++ b/app/assets/javascripts/pipelines/components/pipelines_list/stage.vue @@ -160,7 +160,8 @@ export default { v-gl-tooltip.hover :class="triggerButtonClass" :title="stage.title" - class="mini-pipeline-graph-dropdown-toggle js-builds-dropdown-button" + class="mini-pipeline-graph-dropdown-toggle" + data-testid="mini-pipeline-graph-dropdown-toggle" data-toggle="dropdown" data-display="static" type="button" diff --git a/app/assets/javascripts/search/index.js b/app/assets/javascripts/search/index.js index 0674bff2795..3050b628cd5 100644 --- a/app/assets/javascripts/search/index.js +++ b/app/assets/javascripts/search/index.js @@ -5,6 +5,7 @@ import { queryToObject } from '~/lib/utils/url_utility'; import createStore from './store'; import { initTopbar } from './topbar'; import { initSidebar } from './sidebar'; +import { initSearchSort } from './sort'; export const initSearchApp = () => { // Similar to url_utility.decodeUrlParameter @@ -16,6 +17,7 @@ export const initSearchApp = () => { initTopbar(store); initSidebar(store); + initSearchSort(store); setHighlightClass(query.search); // Code Highlighting refreshCounts(); // Other Scope Tab Counts diff --git a/app/assets/javascripts/search/sort/components/app.vue b/app/assets/javascripts/search/sort/components/app.vue new file mode 100644 index 00000000000..6ce76467c1e --- /dev/null +++ b/app/assets/javascripts/search/sort/components/app.vue @@ -0,0 +1,103 @@ +<script> +import { mapState, mapActions } from 'vuex'; +import { + GlButtonGroup, + GlButton, + GlDropdown, + GlDropdownItem, + GlTooltipDirective, +} from '@gitlab/ui'; +import { SORT_DIRECTION_UI } from '../constants'; + +export default { + name: 'GlobalSearchSort', + components: { + GlButtonGroup, + GlButton, + GlDropdown, + GlDropdownItem, + }, + directives: { + GlTooltip: GlTooltipDirective, + }, + props: { + searchSortOptions: { + type: Array, + required: true, + }, + }, + computed: { + ...mapState(['query']), + selectedSortOption: { + get() { + const { sort } = this.query; + + if (!sort) { + return this.searchSortOptions[0]; + } + + const sortOption = this.searchSortOptions.find((option) => { + if (!option.sortable) { + return option.sortParam === sort; + } + + return Object.values(option.sortParam).indexOf(sort) !== -1; + }); + + // Handle invalid sort param + return sortOption || this.searchSortOptions[0]; + }, + set(value) { + this.setQuery({ key: 'sort', value }); + this.applyQuery(); + }, + }, + sortDirectionData() { + if (!this.selectedSortOption.sortable) { + return SORT_DIRECTION_UI.disabled; + } + + return this.query?.sort?.includes('asc') ? SORT_DIRECTION_UI.asc : SORT_DIRECTION_UI.desc; + }, + }, + methods: { + ...mapActions(['applyQuery', 'setQuery']), + handleSortChange(option) { + if (!option.sortable) { + this.selectedSortOption = option.sortParam; + } else { + // Default new sort options to desc + this.selectedSortOption = option.sortParam.desc; + } + }, + handleSortDirectionChange() { + this.selectedSortOption = + this.sortDirectionData.direction === 'desc' + ? this.selectedSortOption.sortParam.asc + : this.selectedSortOption.sortParam.desc; + }, + }, +}; +</script> + +<template> + <gl-button-group> + <gl-dropdown :text="selectedSortOption.title" :right="true" class="w-100"> + <gl-dropdown-item + v-for="sortOption in searchSortOptions" + :key="sortOption.title" + is-check-item + :is-checked="sortOption.title === selectedSortOption.title" + @click="handleSortChange(sortOption)" + >{{ sortOption.title }}</gl-dropdown-item + > + </gl-dropdown> + <gl-button + v-gl-tooltip + :disabled="!selectedSortOption.sortable" + :title="sortDirectionData.tooltip" + :icon="sortDirectionData.icon" + @click="handleSortDirectionChange" + /> + </gl-button-group> +</template> diff --git a/app/assets/javascripts/search/sort/constants.js b/app/assets/javascripts/search/sort/constants.js new file mode 100644 index 00000000000..575fba5873b --- /dev/null +++ b/app/assets/javascripts/search/sort/constants.js @@ -0,0 +1,19 @@ +import { __ } from '~/locale'; + +export const SORT_DIRECTION_UI = { + disabled: { + direction: null, + tooltip: '', + icon: 'sort-highest', + }, + desc: { + direction: 'desc', + tooltip: __('Sort direction: Descending'), + icon: 'sort-highest', + }, + asc: { + direction: 'asc', + tooltip: __('Sort direction: Ascending'), + icon: 'sort-lowest', + }, +}; diff --git a/app/assets/javascripts/search/sort/index.js b/app/assets/javascripts/search/sort/index.js new file mode 100644 index 00000000000..84bb5175b1d --- /dev/null +++ b/app/assets/javascripts/search/sort/index.js @@ -0,0 +1,27 @@ +import Vue from 'vue'; +import Translate from '~/vue_shared/translate'; +import GlobalSearchSort from './components/app.vue'; + +Vue.use(Translate); + +export const initSearchSort = (store) => { + const el = document.getElementById('js-search-sort'); + + if (!el) return false; + + let { searchSortOptions } = el.dataset; + + searchSortOptions = JSON.parse(searchSortOptions); + + return new Vue({ + el, + store, + render(createElement) { + return createElement(GlobalSearchSort, { + props: { + searchSortOptions, + }, + }); + }, + }); +}; |