summaryrefslogtreecommitdiff
path: root/app/assets
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-02-02 18:09:42 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2021-02-02 18:09:42 +0000
commit2d66c59d593354aa98785899cc8d5e640f62a012 (patch)
treeb0f82a38ffba401a1ad448983785660038c4cf4b /app/assets
parentdab865db1e85e2fc3dd29dae8dc6b8e11b1ba3f7 (diff)
downloadgitlab-ce-2d66c59d593354aa98785899cc8d5e640f62a012.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets')
-rw-r--r--app/assets/javascripts/ci_variable_list/components/ci_variable_popover.vue4
-rw-r--r--app/assets/javascripts/deploy_keys/components/key.vue2
-rw-r--r--app/assets/javascripts/lib/utils/datetime_utility.js121
-rw-r--r--app/assets/javascripts/pages/admin/runners/index.js4
-rw-r--r--app/assets/javascripts/pages/groups/settings/ci_cd/show/index.js4
-rw-r--r--app/assets/javascripts/pages/projects/settings/ci_cd/show/index.js4
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_list/stage.vue3
-rw-r--r--app/assets/javascripts/search/index.js2
-rw-r--r--app/assets/javascripts/search/sort/components/app.vue103
-rw-r--r--app/assets/javascripts/search/sort/constants.js19
-rw-r--r--app/assets/javascripts/search/sort/index.js27
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,
+ },
+ });
+ },
+ });
+};