Skip to content
Snippets Groups Projects
Commit d80f3cd7 authored by GitLab Bot's avatar GitLab Bot
Browse files

Add latest changes from gitlab-org/gitlab@master

parent be81c157
No related branches found
No related tags found
No related merge requests found
Showing
with 276 additions and 63 deletions
<script>
import { GlPopover, GlSprintf, GlButton, GlIcon } from '@gitlab/ui';
import Cookies from 'js-cookie';
import { parseBoolean } from '~/lib/utils/common_utils';
import { s__ } from '~/locale';
import { glEmojiTag } from '~/emoji';
export default {
components: {
GlPopover,
GlSprintf,
GlIcon,
GlButton,
},
props: {
target: {
type: String,
required: true,
},
cssClass: {
type: String,
required: true,
},
dismissKey: {
type: String,
required: true,
},
},
data() {
return {
popoverDismissed: parseBoolean(Cookies.get(this.dismissKey)),
};
},
computed: {
suggestTitle() {
return s__(`suggestPipeline|1/2: Choose a template`);
},
suggestContent() {
return s__(
`suggestPipeline|We recommend the %{boldStart}Code Quality%{boldEnd} template, which will add a report widget to your Merge Requests. This way you’ll learn about code quality degradations much sooner. %{footerStart} Goodbye technical debt! %{footerEnd}`,
);
},
emoji() {
return glEmojiTag('wave');
},
},
methods: {
onDismiss() {
this.popoverDismissed = true;
Cookies.set(this.dismissKey, this.popoverDismissed, { expires: 365 });
},
},
};
</script>
<template>
<gl-popover
v-if="!popoverDismissed"
show
:target="target"
placement="rightbottom"
trigger="manual"
container="viewport"
:css-classes="[cssClass]"
>
<template #title>
<gl-button :aria-label="__('Close')" class="btn-blank float-right" @click="onDismiss">
<gl-icon name="close" aria-hidden="true" />
</gl-button>
{{ suggestTitle }}
</template>
<gl-sprintf :message="suggestContent">
<template #bold="{content}">
<strong> {{ content }} </strong>
</template>
<template #footer="{content}">
<div class="mt-3">
{{ content }}
<span v-html="emoji"></span>
</div>
</template>
</gl-sprintf>
</gl-popover>
</template>
import Vue from 'vue';
import Popover from './components/popover.vue';
export default el =>
new Vue({
el,
render(createElement) {
return createElement(Popover, {
props: {
target: el.dataset.target,
cssClass: el.dataset.cssClass,
dismissKey: el.dataset.dismissKey,
},
});
},
});
// Browser polyfills
/**
* Polyfill: fetch
* @what https://fetch.spec.whatwg.org/
* @why Because Apollo GraphQL client relies on fetch
* @browsers Internet Explorer 11
* @see https://caniuse.com/#feat=fetch
*/
import 'unfetch/polyfill/index';
/**
* Polyfill: FormData APIs
* @what delete(), get(), getAll(), has(), set(), entries(), keys(), values(),
* and support for for...of
* @why Because Apollo GraphQL client relies on fetch
* @browsers Internet Explorer 11, Edge < 18
* @see https://caniuse.com/#feat=mdn-api_formdata and subfeatures
*/
import 'formdata-polyfill';
import './polyfills/custom_event';
import './polyfills/element';
import './polyfills/event';
Loading
Loading
/**
* Polyfill: CustomEvent constructor
* @what new CustomEvent()
* @why Certain features, e.g. notes utilize this
* @browsers Internet Explorer 11
* @see https://caniuse.com/#feat=customevent
*/
if (typeof window.CustomEvent !== 'function') {
window.CustomEvent = function CustomEvent(event, params) {
const evt = document.createEvent('CustomEvent');
Loading
Loading
// polyfill Element.classList and DOMTokenList with classList.js
/**
* Polyfill
* @what Element.classList
* @why In order to align browser features
* @browsers Internet Explorer 11
* @see https://caniuse.com/#feat=classlist
*/
import 'classlist-polyfill';
 
/**
* Polyfill
* @what Element.closest
* @why In order to align browser features
* @browsers Internet Explorer 11
* @see https://caniuse.com/#feat=element-closest
*/
Element.prototype.closest =
Element.prototype.closest ||
function closest(selector, selectedElement = this) {
Loading
Loading
@@ -10,6 +23,13 @@ Element.prototype.closest =
: Element.prototype.closest(selector, selectedElement.parentElement);
};
 
/**
* Polyfill
* @what Element.matches
* @why In order to align browser features
* @browsers Internet Explorer 11
* @see https://caniuse.com/#feat=mdn-api_element_matches
*/
Element.prototype.matches =
Element.prototype.matches ||
Element.prototype.matchesSelector ||
Loading
Loading
@@ -26,7 +46,15 @@ Element.prototype.matches =
return i > -1;
};
 
// From the polyfill on MDN, https://developer.mozilla.org/en-US/docs/Web/API/ChildNode/remove#Polyfill
/**
* Polyfill
* @what ChildNode.remove, Element.remove, CharacterData.remove, DocumentType.remove
* @why In order to align browser features
* @browsers Internet Explorer 11
* @see https://caniuse.com/#feat=childnode-remove
*
* From the polyfill on MDN, https://developer.mozilla.org/en-US/docs/Web/API/ChildNode/remove#Polyfill
*/
(arr => {
arr.forEach(item => {
if (Object.prototype.hasOwnProperty.call(item, 'remove')) {
Loading
Loading
/**
* Polyfill for IE11 support.
* new Event() is not supported by IE11.
* Polyfill: Event constructor
* @what new Event()
* @why To align browser support
* @browsers Internet Explorer 11
* @see https://caniuse.com/#feat=mdn-api_event_event
*
* Although `initEvent` is deprecated for modern browsers it is the one supported by IE
*/
if (typeof window.Event !== 'function') {
Loading
Loading
/**
* Polyfill
* @what NodeList.forEach
* @why To align browser support
* @browsers Internet Explorer 11
* @see https://caniuse.com/#feat=mdn-api_nodelist_foreach
*/
if (window.NodeList && !NodeList.prototype.forEach) {
NodeList.prototype.forEach = function forEach(callback, thisArg = window) {
for (let i = 0; i < this.length; i += 1) {
Loading
Loading
/**
* Polyfill
* @what requestIdleCallback
* @why To align browser features
* @browsers Safari (all versions), Internet Explorer 11
* @see https://caniuse.com/#feat=requestidlecallback
*/
window.requestIdleCallback =
window.requestIdleCallback ||
function requestShim(cb) {
Loading
Loading
/**
* polyfill support for external SVG file references via <use xlink:href>
* @what polyfill support for external SVG file references via <use xlink:href>
* @why This is used in our GitLab SVG icon library
* @browsers Internet Explorer 11
* @see https://caniuse.com/#feat=mdn-svg_elements_use_external_uri
* @see https//css-tricks.com/svg-use-external-source/
*/
import svg4everybody from 'svg4everybody';
 
// polyfill support for external SVG file references via <use xlink:href>
// @see https://css-tricks.com/svg-use-external-source/
svg4everybody();
import _ from 'underscore';
import { uniq } from 'lodash';
import emojiMap from 'emojis/digests.json';
import emojiAliases from 'emojis/aliases.json';
 
Loading
Loading
@@ -18,7 +18,7 @@ export function filterEmojiNames(filter) {
}
 
export function filterEmojiNamesByAlias(filter) {
return _.uniq(filterEmojiNames(filter).map(name => normalizeEmojiName(name)));
return uniq(filterEmojiNames(filter).map(name => normalizeEmojiName(name)));
}
 
let emojiCategoryMap;
Loading
Loading
Loading
Loading
@@ -472,33 +472,6 @@ export default class FilteredSearchManager {
});
input.value = input.value.replace(`${tokenKey}:`, '');
}
const splitSearchToken = searchToken && searchToken.split(' ');
let lastSearchToken = _.last(splitSearchToken);
lastSearchToken = lastSearchToken?.toLowerCase();
/**
* If user writes "milestone", a known token, in the input, we should not
* wait for leading colon to flush it as a filter token.
*/
if (this.filteredSearchTokenKeys.getKeys().includes(lastSearchToken)) {
if (splitSearchToken.length > 1) {
splitSearchToken.pop();
const searchVisualTokens = splitSearchToken.join(' ');
input.value = input.value.replace(searchVisualTokens, '');
FilteredSearchVisualTokens.addSearchVisualToken(searchVisualTokens);
}
FilteredSearchVisualTokens.addFilterVisualToken(lastSearchToken, null, null, {
uppercaseTokenName: this.filteredSearchTokenKeys.shouldUppercaseTokenName(
lastSearchToken,
),
capitalizeTokenValue: this.filteredSearchTokenKeys.shouldCapitalizeTokenValue(
lastSearchToken,
),
});
input.value = input.value.replace(lastSearchToken, '');
}
} else if (!isLastVisualTokenValid && !FilteredSearchVisualTokens.getLastTokenOperator()) {
const tokenKey = FilteredSearchVisualTokens.getLastTokenPartial();
const tokenOperator = searchToken && searchToken.trim();
Loading
Loading
Loading
Loading
@@ -5,6 +5,7 @@ import { getSvgIconPathContent } from '~/lib/utils/icon_utils';
import { chartHeight } from '../../constants';
import { makeDataSeries } from '~/helpers/monitor_helper';
import { graphDataValidatorForValues } from '../../utils';
import { getYAxisOptions, getChartGrid } from './options';
 
export default {
components: {
Loading
Loading
@@ -41,15 +42,25 @@ export default {
values: queryData[0].data,
};
},
chartOptions() {
const yAxis = {
...getYAxisOptions(this.graphData.yAxis),
scale: false,
};
return {
grid: getChartGrid(),
yAxis,
dataZoom: this.dataZoomConfig,
};
},
xAxisTitle() {
return this.graphData.metrics[0].result[0].x_label !== undefined
? this.graphData.metrics[0].result[0].x_label
: '';
},
yAxisTitle() {
return this.graphData.metrics[0].result[0].y_label !== undefined
? this.graphData.metrics[0].result[0].y_label
: '';
return this.chartOptions.yAxis.name;
},
xAxisType() {
return this.graphData.x_type !== undefined ? this.graphData.x_type : 'category';
Loading
Loading
@@ -59,11 +70,6 @@ export default {
 
return handleIcon ? { handleIcon } : {};
},
chartOptions() {
return {
dataZoom: this.dataZoomConfig,
};
},
},
created() {
this.setSvg('scroll-handle');
Loading
Loading
Loading
Loading
@@ -79,7 +79,7 @@ export const fetchData = ({ dispatch }) => {
dispatch('fetchEnvironmentsData');
};
 
export const fetchDashboard = ({ state, dispatch }) => {
export const fetchDashboard = ({ state, commit, dispatch }) => {
dispatch('requestMetricsDashboard');
 
const params = {};
Loading
Loading
@@ -100,6 +100,7 @@ export const fetchDashboard = ({ state, dispatch }) => {
.catch(error => {
Sentry.captureException(error);
 
commit(types.SET_ALL_DASHBOARDS, error.response?.data?.all_dashboards ?? []);
dispatch('receiveMetricsDashboardFailure', error);
 
if (state.showErrorBanner) {
Loading
Loading
import initBlobBundle from '~/blob_edit/blob_bundle';
import initPopover from '~/blob/suggest_gitlab_ci_yml';
 
document.addEventListener('DOMContentLoaded', initBlobBundle);
document.addEventListener('DOMContentLoaded', () => {
initBlobBundle();
const suggestEl = document.querySelector('.js-suggest-gitlab-ci-yml');
if (suggestEl) {
initPopover(suggestEl);
}
});
import initShowRelease from '~/releases/mount_show';
document.addEventListener('DOMContentLoaded', initShowRelease);
<script>
import { mapState, mapActions } from 'vuex';
import { GlButton, GlFormInput, GlFormGroup } from '@gitlab/ui';
import { GlButton, GlLink, GlFormInput, GlFormGroup } from '@gitlab/ui';
import { escape as esc } from 'lodash';
import { __, sprintf } from '~/locale';
import MarkdownField from '~/vue_shared/components/markdown/field.vue';
import autofocusonshow from '~/vue_shared/directives/autofocusonshow';
import { BACK_URL_PARAM } from '~/releases/constants';
import { getParameterByName } from '~/lib/utils/common_utils';
 
export default {
name: 'ReleaseEditApp',
Loading
Loading
@@ -12,6 +14,7 @@ export default {
GlFormInput,
GlFormGroup,
GlButton,
GlLink,
MarkdownField,
},
directives: {
Loading
Loading
@@ -74,6 +77,9 @@ export default {
this.updateReleaseNotes(notes);
},
},
cancelPath() {
return getParameterByName(BACK_URL_PARAM) || this.releasesPagePath;
},
},
created() {
this.fetchRelease();
Loading
Loading
@@ -84,7 +90,6 @@ export default {
'updateRelease',
'updateReleaseTitle',
'updateReleaseNotes',
'navigateToReleasesPage',
]),
},
};
Loading
Loading
@@ -157,15 +162,9 @@ export default {
>
{{ __('Save changes') }}
</gl-button>
<gl-button
class="js-cancel-button"
variant="default"
type="button"
:aria-label="__('Cancel')"
@click="navigateToReleasesPage()"
>
<gl-link :href="cancelPath" class="js-cancel-button btn btn-default">
{{ __('Cancel') }}
</gl-button>
</gl-link>
</div>
</form>
</div>
Loading
Loading
<script>
import { mapState, mapActions } from 'vuex';
import { GlSkeletonLoading } from '@gitlab/ui';
import ReleaseBlock from './release_block.vue';
export default {
name: 'ReleaseShowApp',
components: {
GlSkeletonLoading,
ReleaseBlock,
},
computed: {
...mapState('detail', ['isFetchingRelease', 'fetchError', 'release']),
},
created() {
this.fetchRelease();
},
methods: {
...mapActions('detail', ['fetchRelease']),
},
};
</script>
<template>
<div class="prepend-top-default">
<gl-skeleton-loading v-if="isFetchingRelease" />
<release-block v-else-if="!fetchError" :release="release" />
</div>
</template>
<script>
import { GlTooltipDirective, GlLink, GlBadge } from '@gitlab/ui';
import Icon from '~/vue_shared/components/icon.vue';
import { BACK_URL_PARAM } from '~/releases/constants';
import { setUrlParams } from '~/lib/utils/url_utility';
 
export default {
name: 'ReleaseBlockHeader',
Loading
Loading
@@ -20,7 +22,15 @@ export default {
},
computed: {
editLink() {
return this.release._links?.editUrl;
if (this.release._links?.editUrl) {
const queryParams = {
[BACK_URL_PARAM]: window.location.href,
};
return setUrlParams(queryParams, this.release._links.editUrl);
}
return undefined;
},
selfLink() {
return this.release._links?.self;
Loading
Loading
/* eslint-disable import/prefer-default-export */
// This eslint-disable ^^^ can be removed when at least
// one more constant is added to this file. Currently
// constants.js files with only a single constant
// are flagged by this rule.
export const MAX_MILESTONES_TO_DISPLAY = 5;
export const BACK_URL_PARAM = 'back_url';
Loading
Loading
@@ -6,7 +6,15 @@ import detailModule from './stores/modules/detail';
export default () => {
const el = document.getElementById('js-edit-release-page');
 
const store = createStore({ detail: detailModule });
const store = createStore({
modules: {
detail: detailModule,
},
featureFlags: {
releaseShowPage: Boolean(gon.features?.releaseShowPage),
},
});
store.dispatch('detail/setInitialState', el.dataset);
 
return new Vue({
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment