Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
143a33345c
commit
71722304be
|
@ -168,6 +168,7 @@ Naming/FileName:
|
||||||
- GitLab
|
- GitLab
|
||||||
- JavaScript
|
- JavaScript
|
||||||
- VSCode
|
- VSCode
|
||||||
|
- JetBrains
|
||||||
# default ones:
|
# default ones:
|
||||||
- CLI
|
- CLI
|
||||||
- DSL
|
- DSL
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 2.8 KiB |
|
@ -1,7 +1,7 @@
|
||||||
/* eslint-disable class-methods-use-this */
|
/* eslint-disable class-methods-use-this */
|
||||||
|
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import Cookies from 'js-cookie';
|
import { setCookie } from '~/lib/utils/common_utils';
|
||||||
import createFlash from '~/flash';
|
import createFlash from '~/flash';
|
||||||
import { s__ } from '~/locale';
|
import { s__ } from '~/locale';
|
||||||
import { localTimeAgo } from './lib/utils/datetime_utility';
|
import { localTimeAgo } from './lib/utils/datetime_utility';
|
||||||
|
@ -55,7 +55,7 @@ export default class Activities {
|
||||||
const filter = $sender.attr('id').split('_')[0];
|
const filter = $sender.attr('id').split('_')[0];
|
||||||
|
|
||||||
$('.event-filter .active').removeClass('active');
|
$('.event-filter .active').removeClass('active');
|
||||||
Cookies.set('event_filter', filter);
|
setCookie('event_filter', filter);
|
||||||
|
|
||||||
$sender.closest('li').toggleClass('active');
|
$sender.closest('li').toggleClass('active');
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,10 @@
|
||||||
|
|
||||||
import { GlBreakpointInstance as bp } from '@gitlab/ui/dist/utils';
|
import { GlBreakpointInstance as bp } from '@gitlab/ui/dist/utils';
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import Cookies from 'js-cookie';
|
|
||||||
import { uniq } from 'lodash';
|
import { uniq } from 'lodash';
|
||||||
|
import { getCookie, setCookie, scrollToElement } from '~/lib/utils/common_utils';
|
||||||
import * as Emoji from '~/emoji';
|
import * as Emoji from '~/emoji';
|
||||||
import { scrollToElement } from '~/lib/utils/common_utils';
|
|
||||||
import { dispose, fixTitle } from '~/tooltips';
|
import { dispose, fixTitle } from '~/tooltips';
|
||||||
import createFlash from './flash';
|
import createFlash from './flash';
|
||||||
import axios from './lib/utils/axios_utils';
|
import axios from './lib/utils/axios_utils';
|
||||||
|
@ -506,7 +506,7 @@ export class AwardsHandler {
|
||||||
addEmojiToFrequentlyUsedList(emoji) {
|
addEmojiToFrequentlyUsedList(emoji) {
|
||||||
if (this.emoji.isEmojiNameValid(emoji)) {
|
if (this.emoji.isEmojiNameValid(emoji)) {
|
||||||
this.frequentlyUsedEmojis = uniq(this.getFrequentlyUsedEmojis().concat(emoji));
|
this.frequentlyUsedEmojis = uniq(this.getFrequentlyUsedEmojis().concat(emoji));
|
||||||
Cookies.set('frequently_used_emojis', this.frequentlyUsedEmojis.join(','), { expires: 365 });
|
setCookie('frequently_used_emojis', this.frequentlyUsedEmojis.join(','));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -514,7 +514,7 @@ export class AwardsHandler {
|
||||||
return (
|
return (
|
||||||
this.frequentlyUsedEmojis ||
|
this.frequentlyUsedEmojis ||
|
||||||
(() => {
|
(() => {
|
||||||
const frequentlyUsedEmojis = uniq((Cookies.get('frequently_used_emojis') || '').split(','));
|
const frequentlyUsedEmojis = uniq((getCookie('frequently_used_emojis') || '').split(','));
|
||||||
this.frequentlyUsedEmojis = frequentlyUsedEmojis.filter((inputName) =>
|
this.frequentlyUsedEmojis = frequentlyUsedEmojis.filter((inputName) =>
|
||||||
this.emoji.isEmojiNameValid(inputName),
|
this.emoji.isEmojiNameValid(inputName),
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import Cookies from 'js-cookie';
|
|
||||||
import { flatten } from 'lodash';
|
import { flatten } from 'lodash';
|
||||||
import Mousetrap from 'mousetrap';
|
import Mousetrap from 'mousetrap';
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import { parseBoolean } from '~/lib/utils/common_utils';
|
import { getCookie, setCookie, parseBoolean } from '~/lib/utils/common_utils';
|
||||||
|
|
||||||
import findAndFollowLink from '~/lib/utils/navigation_utility';
|
import findAndFollowLink from '~/lib/utils/navigation_utility';
|
||||||
import { refreshCurrentPage, visitUrl } from '~/lib/utils/url_utility';
|
import { refreshCurrentPage, visitUrl } from '~/lib/utils/url_utility';
|
||||||
import {
|
import {
|
||||||
|
@ -161,10 +161,10 @@ export default class Shortcuts {
|
||||||
static onTogglePerfBar(e) {
|
static onTogglePerfBar(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const performanceBarCookieName = 'perf_bar_enabled';
|
const performanceBarCookieName = 'perf_bar_enabled';
|
||||||
if (parseBoolean(Cookies.get(performanceBarCookieName))) {
|
if (parseBoolean(getCookie(performanceBarCookieName))) {
|
||||||
Cookies.set(performanceBarCookieName, 'false', { expires: 365, path: '/' });
|
setCookie(performanceBarCookieName, 'false', { path: '/' });
|
||||||
} else {
|
} else {
|
||||||
Cookies.set(performanceBarCookieName, 'true', { expires: 365, path: '/' });
|
setCookie(performanceBarCookieName, 'true', { path: '/' });
|
||||||
}
|
}
|
||||||
refreshCurrentPage();
|
refreshCurrentPage();
|
||||||
}
|
}
|
||||||
|
@ -172,8 +172,8 @@ export default class Shortcuts {
|
||||||
static onToggleCanary(e) {
|
static onToggleCanary(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const canaryCookieName = 'gitlab_canary';
|
const canaryCookieName = 'gitlab_canary';
|
||||||
const currentValue = parseBoolean(Cookies.get(canaryCookieName));
|
const currentValue = parseBoolean(getCookie(canaryCookieName));
|
||||||
Cookies.set(canaryCookieName, (!currentValue).toString(), {
|
setCookie(canaryCookieName, (!currentValue).toString(), {
|
||||||
expires: 365,
|
expires: 365,
|
||||||
path: '/',
|
path: '/',
|
||||||
// next.gitlab.com uses a leading period. See https://gitlab.com/gitlab-org/gitlab/-/issues/350186
|
// next.gitlab.com uses a leading period. See https://gitlab.com/gitlab-org/gitlab/-/issues/350186
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<script>
|
<script>
|
||||||
import { GlModal, GlSprintf, GlLink, GlButton } from '@gitlab/ui';
|
import { GlModal, GlSprintf, GlLink, GlButton } from '@gitlab/ui';
|
||||||
import Cookies from 'js-cookie';
|
import { getCookie, removeCookie } from '~/lib/utils/common_utils';
|
||||||
import { __, s__ } from '~/locale';
|
import { __, s__ } from '~/locale';
|
||||||
import Tracking from '~/tracking';
|
import Tracking from '~/tracking';
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ export default {
|
||||||
return this.commitCookiePath || this.projectMergeRequestsPath;
|
return this.commitCookiePath || this.projectMergeRequestsPath;
|
||||||
},
|
},
|
||||||
commitCookiePath() {
|
commitCookiePath() {
|
||||||
const cookieVal = Cookies.get(this.commitCookie);
|
const cookieVal = getCookie(this.commitCookie);
|
||||||
|
|
||||||
if (cookieVal !== 'true') return cookieVal;
|
if (cookieVal !== 'true') return cookieVal;
|
||||||
return '';
|
return '';
|
||||||
|
@ -85,7 +85,7 @@ export default {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
disableModalFromRenderingAgain() {
|
disableModalFromRenderingAgain() {
|
||||||
Cookies.remove(this.commitCookie);
|
removeCookie(this.commitCookie);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import Cookies from 'js-cookie';
|
import { setCookie } from '~/lib/utils/common_utils';
|
||||||
|
|
||||||
const handleOnDismiss = ({ currentTarget }) => {
|
const handleOnDismiss = ({ currentTarget }) => {
|
||||||
currentTarget.removeEventListener('click', handleOnDismiss);
|
currentTarget.removeEventListener('click', handleOnDismiss);
|
||||||
|
@ -6,7 +6,7 @@ const handleOnDismiss = ({ currentTarget }) => {
|
||||||
dataset: { id, expireDate },
|
dataset: { id, expireDate },
|
||||||
} = currentTarget;
|
} = currentTarget;
|
||||||
|
|
||||||
Cookies.set(`hide_broadcast_message_${id}`, true, { expires: new Date(expireDate) });
|
setCookie(`hide_broadcast_message_${id}`, true, { expires: new Date(expireDate) });
|
||||||
|
|
||||||
const notification = document.querySelector(`.js-broadcast-notification-${id}`);
|
const notification = document.querySelector(`.js-broadcast-notification-${id}`);
|
||||||
notification.parentNode.removeChild(notification);
|
notification.parentNode.removeChild(notification);
|
||||||
|
|
|
@ -14,8 +14,8 @@ import {
|
||||||
GlModal,
|
GlModal,
|
||||||
GlSprintf,
|
GlSprintf,
|
||||||
} from '@gitlab/ui';
|
} from '@gitlab/ui';
|
||||||
import Cookies from 'js-cookie';
|
|
||||||
import { mapActions, mapState } from 'vuex';
|
import { mapActions, mapState } from 'vuex';
|
||||||
|
import { getCookie, setCookie } from '~/lib/utils/common_utils';
|
||||||
import { __ } from '~/locale';
|
import { __ } from '~/locale';
|
||||||
import Tracking from '~/tracking';
|
import Tracking from '~/tracking';
|
||||||
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
|
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
|
||||||
|
@ -59,7 +59,7 @@ export default {
|
||||||
mixins: [glFeatureFlagsMixin(), trackingMixin],
|
mixins: [glFeatureFlagsMixin(), trackingMixin],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
isTipDismissed: Cookies.get(AWS_TIP_DISMISSED_COOKIE_NAME) === 'true',
|
isTipDismissed: getCookie(AWS_TIP_DISMISSED_COOKIE_NAME) === 'true',
|
||||||
validationErrorEventProperty: '',
|
validationErrorEventProperty: '',
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -176,7 +176,7 @@ export default {
|
||||||
'setVariableProtected',
|
'setVariableProtected',
|
||||||
]),
|
]),
|
||||||
dismissTip() {
|
dismissTip() {
|
||||||
Cookies.set(AWS_TIP_DISMISSED_COOKIE_NAME, 'true', { expires: 90 });
|
setCookie(AWS_TIP_DISMISSED_COOKIE_NAME, 'true', { expires: 90 });
|
||||||
this.isTipDismissed = true;
|
this.isTipDismissed = true;
|
||||||
},
|
},
|
||||||
deleteVarAndClose() {
|
deleteVarAndClose() {
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
import { GlBreakpointInstance as bp, breakpoints } from '@gitlab/ui/dist/utils';
|
import { GlBreakpointInstance as bp, breakpoints } from '@gitlab/ui/dist/utils';
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import Cookies from 'js-cookie';
|
|
||||||
import { debounce } from 'lodash';
|
import { debounce } from 'lodash';
|
||||||
|
import { getCookie, setCookie, parseBoolean } from '~/lib/utils/common_utils';
|
||||||
import initInviteMembersModal from '~/invite_members/init_invite_members_modal';
|
import initInviteMembersModal from '~/invite_members/init_invite_members_modal';
|
||||||
import initInviteMembersTrigger from '~/invite_members/init_invite_members_trigger';
|
import initInviteMembersTrigger from '~/invite_members/init_invite_members_trigger';
|
||||||
import { parseBoolean } from '~/lib/utils/common_utils';
|
|
||||||
|
|
||||||
export const SIDEBAR_COLLAPSED_CLASS = 'js-sidebar-collapsed';
|
export const SIDEBAR_COLLAPSED_CLASS = 'js-sidebar-collapsed';
|
||||||
|
|
||||||
|
@ -59,7 +58,7 @@ export default class ContextualSidebar {
|
||||||
if (!ContextualSidebar.isDesktopBreakpoint()) {
|
if (!ContextualSidebar.isDesktopBreakpoint()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Cookies.set('sidebar_collapsed', value, { expires: 365 * 10 });
|
setCookie('sidebar_collapsed', value, { expires: 365 * 10 });
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleSidebarNav(show) {
|
toggleSidebarNav(show) {
|
||||||
|
@ -111,7 +110,7 @@ export default class ContextualSidebar {
|
||||||
if (!ContextualSidebar.isDesktopBreakpoint()) {
|
if (!ContextualSidebar.isDesktopBreakpoint()) {
|
||||||
this.toggleSidebarNav(false);
|
this.toggleSidebarNav(false);
|
||||||
} else {
|
} else {
|
||||||
const collapse = parseBoolean(Cookies.get('sidebar_collapsed'));
|
const collapse = parseBoolean(getCookie('sidebar_collapsed'));
|
||||||
this.toggleCollapsedSidebar(collapse, true);
|
this.toggleCollapsedSidebar(collapse, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<script>
|
<script>
|
||||||
import { GlLoadingIcon } from '@gitlab/ui';
|
import { GlLoadingIcon } from '@gitlab/ui';
|
||||||
import Cookies from 'js-cookie';
|
|
||||||
import { mapActions, mapState, mapGetters } from 'vuex';
|
import { mapActions, mapState, mapGetters } from 'vuex';
|
||||||
|
import { getCookie, setCookie } from '~/lib/utils/common_utils';
|
||||||
import { toYmd } from '~/analytics/shared/utils';
|
import { toYmd } from '~/analytics/shared/utils';
|
||||||
import PathNavigation from '~/cycle_analytics/components/path_navigation.vue';
|
import PathNavigation from '~/cycle_analytics/components/path_navigation.vue';
|
||||||
import StageTable from '~/cycle_analytics/components/stage_table.vue';
|
import StageTable from '~/cycle_analytics/components/stage_table.vue';
|
||||||
|
@ -35,7 +35,7 @@ export default {
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
isOverviewDialogDismissed: Cookies.get(OVERVIEW_DIALOG_COOKIE),
|
isOverviewDialogDismissed: getCookie(OVERVIEW_DIALOG_COOKIE),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -134,7 +134,7 @@ export default {
|
||||||
},
|
},
|
||||||
dismissOverviewDialog() {
|
dismissOverviewDialog() {
|
||||||
this.isOverviewDialogDismissed = true;
|
this.isOverviewDialogDismissed = true;
|
||||||
Cookies.set(OVERVIEW_DIALOG_COOKIE, '1', { expires: 365 });
|
setCookie(OVERVIEW_DIALOG_COOKIE, '1');
|
||||||
},
|
},
|
||||||
isUserAllowed(id) {
|
isUserAllowed(id) {
|
||||||
const { permissions } = this;
|
const { permissions } = this;
|
||||||
|
|
|
@ -13,7 +13,6 @@ deprecated_notes_spec.js is the spec for the legacy, jQuery notes application. I
|
||||||
import { GlDeprecatedSkeletonLoading as GlSkeletonLoading } from '@gitlab/ui';
|
import { GlDeprecatedSkeletonLoading as GlSkeletonLoading } from '@gitlab/ui';
|
||||||
import Autosize from 'autosize';
|
import Autosize from 'autosize';
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import Cookies from 'js-cookie';
|
|
||||||
import { escape, uniqueId } from 'lodash';
|
import { escape, uniqueId } from 'lodash';
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import '~/lib/utils/jquery_at_who';
|
import '~/lib/utils/jquery_at_who';
|
||||||
|
@ -28,6 +27,7 @@ import { defaultAutocompleteConfig } from './gfm_auto_complete';
|
||||||
import GLForm from './gl_form';
|
import GLForm from './gl_form';
|
||||||
import axios from './lib/utils/axios_utils';
|
import axios from './lib/utils/axios_utils';
|
||||||
import {
|
import {
|
||||||
|
getCookie,
|
||||||
isInViewport,
|
isInViewport,
|
||||||
getPagePath,
|
getPagePath,
|
||||||
scrollToElement,
|
scrollToElement,
|
||||||
|
@ -121,7 +121,7 @@ export default class Notes {
|
||||||
}
|
}
|
||||||
|
|
||||||
setViewType(view) {
|
setViewType(view) {
|
||||||
this.view = Cookies.get('diff_view') || view;
|
this.view = getCookie('diff_view') || view;
|
||||||
}
|
}
|
||||||
|
|
||||||
addBinding() {
|
addBinding() {
|
||||||
|
@ -473,7 +473,7 @@ export default class Notes {
|
||||||
}
|
}
|
||||||
|
|
||||||
isParallelView() {
|
isParallelView() {
|
||||||
return Cookies.get('diff_view') === 'parallel';
|
return getCookie('diff_view') === 'parallel';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<script>
|
<script>
|
||||||
import { GlCollapse, GlButton, GlPopover } from '@gitlab/ui';
|
import { GlCollapse, GlButton, GlPopover } from '@gitlab/ui';
|
||||||
import Cookies from 'js-cookie';
|
import { getCookie, setCookie, parseBoolean, isLoggedIn } from '~/lib/utils/common_utils';
|
||||||
import { parseBoolean, isLoggedIn } from '~/lib/utils/common_utils';
|
|
||||||
import { s__ } from '~/locale';
|
import { s__ } from '~/locale';
|
||||||
import Participants from '~/sidebar/components/participants/participants.vue';
|
import Participants from '~/sidebar/components/participants/participants.vue';
|
||||||
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
|
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
|
||||||
|
@ -53,7 +53,7 @@ export default {
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
isResolvedCommentsPopoverHidden: parseBoolean(Cookies.get(this.$options.cookieKey)),
|
isResolvedCommentsPopoverHidden: parseBoolean(getCookie(this.$options.cookieKey)),
|
||||||
discussionWithOpenForm: '',
|
discussionWithOpenForm: '',
|
||||||
isLoggedIn: isLoggedIn(),
|
isLoggedIn: isLoggedIn(),
|
||||||
};
|
};
|
||||||
|
@ -96,7 +96,7 @@ export default {
|
||||||
methods: {
|
methods: {
|
||||||
handleSidebarClick() {
|
handleSidebarClick() {
|
||||||
this.isResolvedCommentsPopoverHidden = true;
|
this.isResolvedCommentsPopoverHidden = true;
|
||||||
Cookies.set(this.$options.cookieKey, 'true', { expires: 365 * 10 });
|
setCookie(this.$options.cookieKey, 'true', { expires: 365 * 10 });
|
||||||
this.updateActiveDiscussion();
|
this.updateActiveDiscussion();
|
||||||
},
|
},
|
||||||
updateActiveDiscussion(id) {
|
updateActiveDiscussion(id) {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import Cookies from 'js-cookie';
|
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import { mapActions, mapState, mapGetters } from 'vuex';
|
import { mapActions, mapState, mapGetters } from 'vuex';
|
||||||
import { parseBoolean } from '~/lib/utils/common_utils';
|
import { getCookie, setCookie, parseBoolean, removeCookie } from '~/lib/utils/common_utils';
|
||||||
|
|
||||||
import { getParameterValues } from '~/lib/utils/url_utility';
|
import { getParameterValues } from '~/lib/utils/url_utility';
|
||||||
import eventHub from '../notes/event_hub';
|
import eventHub from '../notes/event_hub';
|
||||||
import diffsApp from './components/app.vue';
|
import diffsApp from './components/app.vue';
|
||||||
|
@ -58,14 +58,14 @@ export default function initDiffsApp(store) {
|
||||||
// Check for cookie and save that setting for future use.
|
// Check for cookie and save that setting for future use.
|
||||||
// Then delete the cookie as we are phasing it out and using the database as SSOT.
|
// Then delete the cookie as we are phasing it out and using the database as SSOT.
|
||||||
// NOTE: This can/should be removed later
|
// NOTE: This can/should be removed later
|
||||||
if (Cookies.get(DIFF_WHITESPACE_COOKIE_NAME)) {
|
if (getCookie(DIFF_WHITESPACE_COOKIE_NAME)) {
|
||||||
const hideWhitespace = Cookies.get(DIFF_WHITESPACE_COOKIE_NAME);
|
const hideWhitespace = getCookie(DIFF_WHITESPACE_COOKIE_NAME);
|
||||||
this.setShowWhitespace({
|
this.setShowWhitespace({
|
||||||
url: this.endpointUpdateUser,
|
url: this.endpointUpdateUser,
|
||||||
showWhitespace: hideWhitespace !== '1',
|
showWhitespace: hideWhitespace !== '1',
|
||||||
trackClick: false,
|
trackClick: false,
|
||||||
});
|
});
|
||||||
Cookies.remove(DIFF_WHITESPACE_COOKIE_NAME);
|
removeCookie(DIFF_WHITESPACE_COOKIE_NAME);
|
||||||
} else {
|
} else {
|
||||||
// This is only to set the the user preference in Vuex for use later
|
// This is only to set the the user preference in Vuex for use later
|
||||||
this.setShowWhitespace({
|
this.setShowWhitespace({
|
||||||
|
@ -77,7 +77,7 @@ export default function initDiffsApp(store) {
|
||||||
|
|
||||||
const vScrollingParam = getParameterValues('virtual_scrolling')[0];
|
const vScrollingParam = getParameterValues('virtual_scrolling')[0];
|
||||||
if (vScrollingParam === 'false' || vScrollingParam === 'true') {
|
if (vScrollingParam === 'false' || vScrollingParam === 'true') {
|
||||||
Cookies.set('diffs_virtual_scrolling', vScrollingParam);
|
setCookie('diffs_virtual_scrolling', vScrollingParam);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
|
@ -1,9 +1,14 @@
|
||||||
import Cookies from 'js-cookie';
|
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
|
import {
|
||||||
|
setCookie,
|
||||||
|
handleLocationHash,
|
||||||
|
historyPushState,
|
||||||
|
scrollToElement,
|
||||||
|
} from '~/lib/utils/common_utils';
|
||||||
import createFlash from '~/flash';
|
import createFlash from '~/flash';
|
||||||
import { diffViewerModes } from '~/ide/constants';
|
import { diffViewerModes } from '~/ide/constants';
|
||||||
import axios from '~/lib/utils/axios_utils';
|
import axios from '~/lib/utils/axios_utils';
|
||||||
import { handleLocationHash, historyPushState, scrollToElement } from '~/lib/utils/common_utils';
|
|
||||||
import httpStatusCodes from '~/lib/utils/http_status';
|
import httpStatusCodes from '~/lib/utils/http_status';
|
||||||
import Poll from '~/lib/utils/poll';
|
import Poll from '~/lib/utils/poll';
|
||||||
import { mergeUrlParams, getLocationHash } from '~/lib/utils/url_utility';
|
import { mergeUrlParams, getLocationHash } from '~/lib/utils/url_utility';
|
||||||
|
@ -369,7 +374,7 @@ export const setRenderIt = ({ commit }, file) => commit(types.RENDER_FILE, file)
|
||||||
export const setInlineDiffViewType = ({ commit }) => {
|
export const setInlineDiffViewType = ({ commit }) => {
|
||||||
commit(types.SET_DIFF_VIEW_TYPE, INLINE_DIFF_VIEW_TYPE);
|
commit(types.SET_DIFF_VIEW_TYPE, INLINE_DIFF_VIEW_TYPE);
|
||||||
|
|
||||||
Cookies.set(DIFF_VIEW_COOKIE_NAME, INLINE_DIFF_VIEW_TYPE);
|
setCookie(DIFF_VIEW_COOKIE_NAME, INLINE_DIFF_VIEW_TYPE);
|
||||||
const url = mergeUrlParams({ view: INLINE_DIFF_VIEW_TYPE }, window.location.href);
|
const url = mergeUrlParams({ view: INLINE_DIFF_VIEW_TYPE }, window.location.href);
|
||||||
historyPushState(url);
|
historyPushState(url);
|
||||||
|
|
||||||
|
@ -381,7 +386,7 @@ export const setInlineDiffViewType = ({ commit }) => {
|
||||||
export const setParallelDiffViewType = ({ commit }) => {
|
export const setParallelDiffViewType = ({ commit }) => {
|
||||||
commit(types.SET_DIFF_VIEW_TYPE, PARALLEL_DIFF_VIEW_TYPE);
|
commit(types.SET_DIFF_VIEW_TYPE, PARALLEL_DIFF_VIEW_TYPE);
|
||||||
|
|
||||||
Cookies.set(DIFF_VIEW_COOKIE_NAME, PARALLEL_DIFF_VIEW_TYPE);
|
setCookie(DIFF_VIEW_COOKIE_NAME, PARALLEL_DIFF_VIEW_TYPE);
|
||||||
const url = mergeUrlParams({ view: PARALLEL_DIFF_VIEW_TYPE }, window.location.href);
|
const url = mergeUrlParams({ view: PARALLEL_DIFF_VIEW_TYPE }, window.location.href);
|
||||||
historyPushState(url);
|
historyPushState(url);
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import Cookies from 'js-cookie';
|
import { getCookie } from '~/lib/utils/common_utils';
|
||||||
import { getParameterValues } from '~/lib/utils/url_utility';
|
import { getParameterValues } from '~/lib/utils/url_utility';
|
||||||
import { __, n__ } from '~/locale';
|
import { __, n__ } from '~/locale';
|
||||||
import {
|
import {
|
||||||
|
@ -175,7 +175,7 @@ export function suggestionCommitMessage(state, _, rootState) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const isVirtualScrollingEnabled = (state) => {
|
export const isVirtualScrollingEnabled = (state) => {
|
||||||
const vSrollerCookie = Cookies.get('diffs_virtual_scrolling');
|
const vSrollerCookie = getCookie('diffs_virtual_scrolling');
|
||||||
|
|
||||||
if (state.disableVirtualScroller) {
|
if (state.disableVirtualScroller) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import Cookies from 'js-cookie';
|
import { getCookie } from '~/lib/utils/common_utils';
|
||||||
import { getParameterValues } from '~/lib/utils/url_utility';
|
import { getParameterValues } from '~/lib/utils/url_utility';
|
||||||
import { INLINE_DIFF_VIEW_TYPE, DIFF_VIEW_COOKIE_NAME } from '../../constants';
|
import { INLINE_DIFF_VIEW_TYPE, DIFF_VIEW_COOKIE_NAME } from '../../constants';
|
||||||
|
|
||||||
const getViewTypeFromQueryString = () => getParameterValues('view')[0];
|
const getViewTypeFromQueryString = () => getParameterValues('view')[0];
|
||||||
|
|
||||||
const viewTypeFromCookie = Cookies.get(DIFF_VIEW_COOKIE_NAME);
|
const viewTypeFromCookie = getCookie(DIFF_VIEW_COOKIE_NAME);
|
||||||
const defaultViewType = INLINE_DIFF_VIEW_TYPE;
|
const defaultViewType = INLINE_DIFF_VIEW_TYPE;
|
||||||
|
|
||||||
export default () => ({
|
export default () => ({
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import Cookies from 'js-cookie';
|
|
||||||
import { chunk, memoize, uniq } from 'lodash';
|
import { chunk, memoize, uniq } from 'lodash';
|
||||||
|
import { getCookie, setCookie } from '~/lib/utils/common_utils';
|
||||||
import { initEmojiMap, getEmojiCategoryMap } from '~/emoji';
|
import { initEmojiMap, getEmojiCategoryMap } from '~/emoji';
|
||||||
import {
|
import {
|
||||||
EMOJIS_PER_ROW,
|
EMOJIS_PER_ROW,
|
||||||
|
@ -13,7 +13,7 @@ export const generateCategoryHeight = (emojisLength) =>
|
||||||
emojisLength * EMOJI_ROW_HEIGHT + CATEGORY_ROW_HEIGHT;
|
emojisLength * EMOJI_ROW_HEIGHT + CATEGORY_ROW_HEIGHT;
|
||||||
|
|
||||||
export const getFrequentlyUsedEmojis = () => {
|
export const getFrequentlyUsedEmojis = () => {
|
||||||
const savedEmojis = Cookies.get(FREQUENTLY_USED_COOKIE_KEY);
|
const savedEmojis = getCookie(FREQUENTLY_USED_COOKIE_KEY);
|
||||||
|
|
||||||
if (!savedEmojis) return null;
|
if (!savedEmojis) return null;
|
||||||
|
|
||||||
|
@ -30,13 +30,13 @@ export const getFrequentlyUsedEmojis = () => {
|
||||||
|
|
||||||
export const addToFrequentlyUsed = (emoji) => {
|
export const addToFrequentlyUsed = (emoji) => {
|
||||||
const frequentlyUsedEmojis = uniq(
|
const frequentlyUsedEmojis = uniq(
|
||||||
(Cookies.get(FREQUENTLY_USED_COOKIE_KEY) || '')
|
(getCookie(FREQUENTLY_USED_COOKIE_KEY) || '')
|
||||||
.split(',')
|
.split(',')
|
||||||
.filter((e) => e)
|
.filter((e) => e)
|
||||||
.concat(emoji),
|
.concat(emoji),
|
||||||
);
|
);
|
||||||
|
|
||||||
Cookies.set(FREQUENTLY_USED_COOKIE_KEY, frequentlyUsedEmojis.join(','), { expires: 365 });
|
setCookie(FREQUENTLY_USED_COOKIE_KEY, frequentlyUsedEmojis.join(','));
|
||||||
};
|
};
|
||||||
|
|
||||||
export const hasFrequentlyUsedEmojis = () => getFrequentlyUsedEmojis() !== null;
|
export const hasFrequentlyUsedEmojis = () => getFrequentlyUsedEmojis() !== null;
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* causes reflows, visit https://gist.github.com/paulirish/5d52fb081b3570c81e3a
|
* causes reflows, visit https://gist.github.com/paulirish/5d52fb081b3570c81e3a
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Cookies from 'js-cookie';
|
import { getCookie } from '~/lib/utils/common_utils';
|
||||||
|
|
||||||
const LINE_NUMBER_CLASS = 'diff-line-num';
|
const LINE_NUMBER_CLASS = 'diff-line-num';
|
||||||
const UNFOLDABLE_LINE_CLASS = 'js-unfold';
|
const UNFOLDABLE_LINE_CLASS = 'js-unfold';
|
||||||
|
@ -29,7 +29,7 @@ export default {
|
||||||
$diffFile.closest(DIFF_CONTAINER_SELECTOR).data('canCreateNote') === '';
|
$diffFile.closest(DIFF_CONTAINER_SELECTOR).data('canCreateNote') === '';
|
||||||
}
|
}
|
||||||
|
|
||||||
this.isParallelView = Cookies.get('diff_view') === 'parallel';
|
this.isParallelView = getCookie('diff_view') === 'parallel';
|
||||||
|
|
||||||
if (this.userCanCreateNote) {
|
if (this.userCanCreateNote) {
|
||||||
$diffFile
|
$diffFile
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import Cookies from 'js-cookie';
|
import { getCookie, setCookie, parseBoolean } from '~/lib/utils/common_utils';
|
||||||
import { parseBoolean } from '~/lib/utils/common_utils';
|
|
||||||
|
|
||||||
class Landing {
|
class Landing {
|
||||||
constructor(landingElement, dismissButton, cookieName) {
|
constructor(landingElement, dismissButton, cookieName) {
|
||||||
|
@ -27,11 +26,11 @@ class Landing {
|
||||||
|
|
||||||
dismissLanding() {
|
dismissLanding() {
|
||||||
this.landingElement.classList.add('hidden');
|
this.landingElement.classList.add('hidden');
|
||||||
Cookies.set(this.cookieName, 'true', { expires: 365 });
|
setCookie(this.cookieName, 'true');
|
||||||
}
|
}
|
||||||
|
|
||||||
isDismissed() {
|
isDismissed() {
|
||||||
return parseBoolean(Cookies.get(this.cookieName));
|
return parseBoolean(getCookie(this.cookieName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { GlBreakpointInstance as bp } from '@gitlab/ui/dist/utils';
|
import { GlBreakpointInstance as bp } from '@gitlab/ui/dist/utils';
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import Cookies from 'js-cookie';
|
import { setCookie } from '~/lib/utils/common_utils';
|
||||||
import { loadCSSFile } from '~/lib/utils/css_utils';
|
import { loadCSSFile } from '~/lib/utils/css_utils';
|
||||||
import UsersSelect from '~/users_select';
|
import UsersSelect from '~/users_select';
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ export default class IssuableContext {
|
||||||
const supportedSizes = ['xs', 'sm', 'md'];
|
const supportedSizes = ['xs', 'sm', 'md'];
|
||||||
|
|
||||||
if (supportedSizes.includes(bpBreakpoint)) {
|
if (supportedSizes.includes(bpBreakpoint)) {
|
||||||
Cookies.set('collapsed_gutter', true);
|
setCookie('collapsed_gutter', true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -705,7 +705,10 @@ export const scopedLabelKey = ({ title = '' }) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Methods to set and get Cookie
|
// Methods to set and get Cookie
|
||||||
export const setCookie = (name, value) => Cookies.set(name, value, { expires: 365 });
|
export const setCookie = (name, value, attributes) => {
|
||||||
|
const defaults = { expires: 365, secure: Boolean(window.gon?.secure) };
|
||||||
|
Cookies.set(name, value, { ...defaults, ...attributes });
|
||||||
|
};
|
||||||
|
|
||||||
export const getCookie = (name) => Cookies.get(name);
|
export const getCookie = (name) => Cookies.get(name);
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import Cookies from 'js-cookie';
|
import { setCookie } from '~/lib/utils/common_utils';
|
||||||
import createFlash from '~/flash';
|
import createFlash from '~/flash';
|
||||||
import axios from '~/lib/utils/axios_utils';
|
import axios from '~/lib/utils/axios_utils';
|
||||||
import { __ } from '~/locale';
|
import { __ } from '~/locale';
|
||||||
|
@ -51,7 +51,7 @@ export const setFailedRequest = ({ commit }, message) => {
|
||||||
|
|
||||||
export const setViewType = ({ commit }, viewType) => {
|
export const setViewType = ({ commit }, viewType) => {
|
||||||
commit(types.SET_VIEW_TYPE, viewType);
|
commit(types.SET_VIEW_TYPE, viewType);
|
||||||
Cookies.set('diff_view', viewType);
|
setCookie('diff_view', viewType);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const setSubmitState = ({ commit }, isSubmitting) => {
|
export const setSubmitState = ({ commit }, isSubmitting) => {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import Cookies from 'js-cookie';
|
import { getCookie } from '~/lib/utils/common_utils';
|
||||||
import { VIEW_TYPES } from '../constants';
|
import { VIEW_TYPES } from '../constants';
|
||||||
|
|
||||||
const diffViewType = Cookies.get('diff_view');
|
const diffViewType = getCookie('diff_view');
|
||||||
|
|
||||||
export default () => ({
|
export default () => ({
|
||||||
isLoading: true,
|
isLoading: true,
|
||||||
|
|
|
@ -1,20 +1,21 @@
|
||||||
/* eslint-disable no-new, class-methods-use-this */
|
/* eslint-disable no-new, class-methods-use-this */
|
||||||
import { GlBreakpointInstance as bp } from '@gitlab/ui/dist/utils';
|
import { GlBreakpointInstance as bp } from '@gitlab/ui/dist/utils';
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import Cookies from 'js-cookie';
|
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
|
import {
|
||||||
|
getCookie,
|
||||||
|
parseUrlPathname,
|
||||||
|
isMetaClick,
|
||||||
|
parseBoolean,
|
||||||
|
scrollToElement,
|
||||||
|
} from '~/lib/utils/common_utils';
|
||||||
import createEventHub from '~/helpers/event_hub_factory';
|
import createEventHub from '~/helpers/event_hub_factory';
|
||||||
import BlobForkSuggestion from './blob/blob_fork_suggestion';
|
import BlobForkSuggestion from './blob/blob_fork_suggestion';
|
||||||
import Diff from './diff';
|
import Diff from './diff';
|
||||||
import createFlash from './flash';
|
import createFlash from './flash';
|
||||||
import { initDiffStatsDropdown } from './init_diff_stats_dropdown';
|
import { initDiffStatsDropdown } from './init_diff_stats_dropdown';
|
||||||
import axios from './lib/utils/axios_utils';
|
import axios from './lib/utils/axios_utils';
|
||||||
import {
|
|
||||||
parseUrlPathname,
|
|
||||||
isMetaClick,
|
|
||||||
parseBoolean,
|
|
||||||
scrollToElement,
|
|
||||||
} from './lib/utils/common_utils';
|
|
||||||
import { localTimeAgo } from './lib/utils/datetime_utility';
|
import { localTimeAgo } from './lib/utils/datetime_utility';
|
||||||
import { isInVueNoteablePage } from './lib/utils/dom_utils';
|
import { isInVueNoteablePage } from './lib/utils/dom_utils';
|
||||||
import { __ } from './locale';
|
import { __ } from './locale';
|
||||||
|
@ -514,7 +515,7 @@ export default class MergeRequestTabs {
|
||||||
|
|
||||||
// Expand the issuable sidebar unless the user explicitly collapsed it
|
// Expand the issuable sidebar unless the user explicitly collapsed it
|
||||||
expandView() {
|
expandView() {
|
||||||
if (parseBoolean(Cookies.get('collapsed_gutter'))) {
|
if (parseBoolean(getCookie('collapsed_gutter'))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const $gutterBtn = $('.js-sidebar-toggle');
|
const $gutterBtn = $('.js-sidebar-toggle');
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<script>
|
<script>
|
||||||
import { GlButton } from '@gitlab/ui';
|
import { GlButton } from '@gitlab/ui';
|
||||||
import Cookies from 'js-cookie';
|
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import { parseBoolean } from '~/lib/utils/common_utils';
|
import { getCookie, setCookie, parseBoolean } from '~/lib/utils/common_utils';
|
||||||
|
|
||||||
import Translate from '../../../../../vue_shared/translate';
|
import Translate from '../../../../../vue_shared/translate';
|
||||||
|
|
||||||
Vue.use(Translate);
|
Vue.use(Translate);
|
||||||
|
@ -17,13 +17,13 @@ export default {
|
||||||
inject: ['docsUrl', 'illustrationUrl'],
|
inject: ['docsUrl', 'illustrationUrl'],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
calloutDismissed: parseBoolean(Cookies.get(cookieKey)),
|
calloutDismissed: parseBoolean(getCookie(cookieKey)),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
dismissCallout() {
|
dismissCallout() {
|
||||||
this.calloutDismissed = true;
|
this.calloutDismissed = true;
|
||||||
Cookies.set(cookieKey, this.calloutDismissed, { expires: 365 });
|
setCookie(cookieKey, this.calloutDismissed);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* eslint-disable func-names, no-return-assign */
|
/* eslint-disable func-names, no-return-assign */
|
||||||
|
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import Cookies from 'js-cookie';
|
import { setCookie } from '~/lib/utils/common_utils';
|
||||||
import initClonePanel from '~/clone_panel';
|
import initClonePanel from '~/clone_panel';
|
||||||
import initDeprecatedJQueryDropdown from '~/deprecated_jquery_dropdown';
|
import initDeprecatedJQueryDropdown from '~/deprecated_jquery_dropdown';
|
||||||
import createFlash from '~/flash';
|
import createFlash from '~/flash';
|
||||||
|
@ -24,19 +24,19 @@ export default class Project {
|
||||||
}
|
}
|
||||||
|
|
||||||
$('.js-hide-no-ssh-message').on('click', function (e) {
|
$('.js-hide-no-ssh-message').on('click', function (e) {
|
||||||
Cookies.set('hide_no_ssh_message', 'false');
|
setCookie('hide_no_ssh_message', 'false');
|
||||||
$(this).parents('.js-no-ssh-key-message').remove();
|
$(this).parents('.js-no-ssh-key-message').remove();
|
||||||
return e.preventDefault();
|
return e.preventDefault();
|
||||||
});
|
});
|
||||||
$('.js-hide-no-password-message').on('click', function (e) {
|
$('.js-hide-no-password-message').on('click', function (e) {
|
||||||
Cookies.set('hide_no_password_message', 'false');
|
setCookie('hide_no_password_message', 'false');
|
||||||
$(this).parents('.js-no-password-message').remove();
|
$(this).parents('.js-no-password-message').remove();
|
||||||
return e.preventDefault();
|
return e.preventDefault();
|
||||||
});
|
});
|
||||||
$('.hide-auto-devops-implicitly-enabled-banner').on('click', function (e) {
|
$('.hide-auto-devops-implicitly-enabled-banner').on('click', function (e) {
|
||||||
const projectId = $(this).data('project-id');
|
const projectId = $(this).data('project-id');
|
||||||
const cookieKey = `hide_auto_devops_implicitly_enabled_banner_${projectId}`;
|
const cookieKey = `hide_auto_devops_implicitly_enabled_banner_${projectId}`;
|
||||||
Cookies.set(cookieKey, 'false');
|
setCookie(cookieKey, 'false');
|
||||||
$(this).parents('.auto-devops-implicitly-enabled-banner').remove();
|
$(this).parents('.auto-devops-implicitly-enabled-banner').remove();
|
||||||
return e.preventDefault();
|
return e.preventDefault();
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import Cookies from 'js-cookie';
|
import { setCookie } from '~/lib/utils/common_utils';
|
||||||
import UserCallout from '~/user_callout';
|
import UserCallout from '~/user_callout';
|
||||||
import UserTabs from './user_tabs';
|
import UserTabs from './user_tabs';
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ function initUserProfile(action) {
|
||||||
// hide project limit message
|
// hide project limit message
|
||||||
$('.hide-project-limit-message').on('click', (e) => {
|
$('.hide-project-limit-message').on('click', (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
Cookies.set('hide_project_limit_message', 'false');
|
setCookie('hide_project_limit_message', 'false');
|
||||||
$(this).parents('.project-limit-message').remove();
|
$(this).parents('.project-limit-message').remove();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* eslint-disable func-names, consistent-return, no-param-reassign */
|
/* eslint-disable func-names, consistent-return, no-param-reassign */
|
||||||
|
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import Cookies from 'js-cookie';
|
import { setCookie } from '~/lib/utils/common_utils';
|
||||||
import { hide, fixTitle } from '~/tooltips';
|
import { hide, fixTitle } from '~/tooltips';
|
||||||
import createFlash from './flash';
|
import createFlash from './flash';
|
||||||
import axios from './lib/utils/axios_utils';
|
import axios from './lib/utils/axios_utils';
|
||||||
|
@ -80,7 +80,7 @@ Sidebar.prototype.sidebarToggleClicked = function (e, triggered) {
|
||||||
hide($this);
|
hide($this);
|
||||||
|
|
||||||
if (!triggered) {
|
if (!triggered) {
|
||||||
Cookies.set('collapsed_gutter', $('.right-sidebar').hasClass('right-sidebar-collapsed'));
|
setCookie('collapsed_gutter', $('.right-sidebar').hasClass('right-sidebar-collapsed'));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
<script>
|
<script>
|
||||||
import { GlBanner } from '@gitlab/ui';
|
import { GlBanner } from '@gitlab/ui';
|
||||||
import Cookies from 'js-cookie';
|
import { getCookie, setCookie, parseBoolean } from '~/lib/utils/common_utils';
|
||||||
import { parseBoolean } from '~/lib/utils/common_utils';
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
|
@ -19,13 +18,13 @@ export default {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
if (parseBoolean(Cookies.get('hide_serverless_survey'))) {
|
if (parseBoolean(getCookie('hide_serverless_survey'))) {
|
||||||
this.visible = false;
|
this.visible = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
handleClose() {
|
handleClose() {
|
||||||
Cookies.set('hide_serverless_survey', 'true', { expires: 365 * 10 });
|
setCookie('hide_serverless_survey', 'true', { expires: 365 * 10 });
|
||||||
this.visible = false;
|
this.visible = false;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import Cookies from 'js-cookie';
|
import { getCookie, setCookie } from '~/lib/utils/common_utils';
|
||||||
|
|
||||||
export default class UserCallout {
|
export default class UserCallout {
|
||||||
constructor(options = {}) {
|
constructor(options = {}) {
|
||||||
|
@ -9,7 +9,7 @@ export default class UserCallout {
|
||||||
|
|
||||||
this.userCalloutBody = $(`.${className}`);
|
this.userCalloutBody = $(`.${className}`);
|
||||||
this.cookieName = this.userCalloutBody.data('uid');
|
this.cookieName = this.userCalloutBody.data('uid');
|
||||||
this.isCalloutDismissed = Cookies.get(this.cookieName);
|
this.isCalloutDismissed = getCookie(this.cookieName);
|
||||||
this.init();
|
this.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ export default class UserCallout {
|
||||||
cookieOptions.path = this.userCalloutBody.data('projectPath');
|
cookieOptions.path = this.userCalloutBody.data('projectPath');
|
||||||
}
|
}
|
||||||
|
|
||||||
Cookies.set(this.cookieName, 'true', cookieOptions);
|
setCookie(this.cookieName, 'true', cookieOptions);
|
||||||
|
|
||||||
if ($currentTarget.hasClass('close') || $currentTarget.hasClass('js-close')) {
|
if ($currentTarget.hasClass('close') || $currentTarget.hasClass('js-close')) {
|
||||||
this.userCalloutBody.remove();
|
this.userCalloutBody.remove();
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import Cookies from 'js-cookie';
|
import { setCookie, parseBoolean } from '~/lib/utils/common_utils';
|
||||||
import { parseBoolean } from '~/lib/utils/common_utils';
|
|
||||||
import DismissibleAlert from '~/vue_shared/components/dismissible_alert.vue';
|
import DismissibleAlert from '~/vue_shared/components/dismissible_alert.vue';
|
||||||
|
|
||||||
const getCookieExpirationPeriod = (expirationPeriod) => {
|
const getCookieExpirationPeriod = (expirationPeriod) => {
|
||||||
|
@ -33,7 +33,7 @@ const mountVueAlert = (el) => {
|
||||||
if (!dismissCookieName) {
|
if (!dismissCookieName) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Cookies.set(dismissCookieName, true, {
|
setCookie(dismissCookieName, true, {
|
||||||
expires: getCookieExpirationPeriod(dismissCookieExpire),
|
expires: getCookieExpirationPeriod(dismissCookieExpire),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<script>
|
<script>
|
||||||
import { GlIcon } from '@gitlab/ui';
|
import { GlIcon } from '@gitlab/ui';
|
||||||
import { GlBreakpointInstance as bp } from '@gitlab/ui/dist/utils';
|
import { GlBreakpointInstance as bp } from '@gitlab/ui/dist/utils';
|
||||||
import Cookies from 'js-cookie';
|
import { getCookie, setCookie, parseBoolean } from '~/lib/utils/common_utils';
|
||||||
import { parseBoolean } from '~/lib/utils/common_utils';
|
|
||||||
import { USER_COLLAPSED_GUTTER_COOKIE } from '../constants';
|
import { USER_COLLAPSED_GUTTER_COOKIE } from '../constants';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -10,7 +10,7 @@ export default {
|
||||||
GlIcon,
|
GlIcon,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
const userExpanded = !parseBoolean(Cookies.get(USER_COLLAPSED_GUTTER_COOKIE));
|
const userExpanded = !parseBoolean(getCookie(USER_COLLAPSED_GUTTER_COOKIE));
|
||||||
|
|
||||||
// We're deliberately keeping two different props for sidebar status;
|
// We're deliberately keeping two different props for sidebar status;
|
||||||
// 1. userExpanded reflects value based on cookie `collapsed_gutter`.
|
// 1. userExpanded reflects value based on cookie `collapsed_gutter`.
|
||||||
|
@ -46,7 +46,7 @@ export default {
|
||||||
this.isExpanded = !this.isExpanded;
|
this.isExpanded = !this.isExpanded;
|
||||||
this.userExpanded = this.isExpanded;
|
this.userExpanded = this.isExpanded;
|
||||||
|
|
||||||
Cookies.set(USER_COLLAPSED_GUTTER_COOKIE, !this.userExpanded);
|
setCookie(USER_COLLAPSED_GUTTER_COOKIE, !this.userExpanded);
|
||||||
this.updatePageContainerClass();
|
this.updatePageContainerClass();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -259,10 +259,9 @@ $tabs-holder-z-index: 250;
|
||||||
> span {
|
> span {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
max-width: 12.5em;
|
max-width: 12.5em;
|
||||||
margin-bottom: -3px;
|
margin-bottom: -6px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
line-height: 14px;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ class GraphqlController < ApplicationController
|
||||||
before_action :authorize_access_api!
|
before_action :authorize_access_api!
|
||||||
before_action :set_user_last_activity
|
before_action :set_user_last_activity
|
||||||
before_action :track_vs_code_usage
|
before_action :track_vs_code_usage
|
||||||
|
before_action :track_jetbrains_usage
|
||||||
before_action :disable_query_limiting
|
before_action :disable_query_limiting
|
||||||
before_action :limit_query_size
|
before_action :limit_query_size
|
||||||
|
|
||||||
|
@ -137,6 +138,11 @@ class GraphqlController < ApplicationController
|
||||||
.track_api_request_when_trackable(user_agent: request.user_agent, user: current_user)
|
.track_api_request_when_trackable(user_agent: request.user_agent, user: current_user)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def track_jetbrains_usage
|
||||||
|
Gitlab::UsageDataCounters::JetBrainsPluginActivityUniqueCounter
|
||||||
|
.track_api_request_when_trackable(user_agent: request.user_agent, user: current_user)
|
||||||
|
end
|
||||||
|
|
||||||
def execute_multiplex
|
def execute_multiplex
|
||||||
GitlabSchema.multiplex(multiplex_queries, context: context)
|
GitlabSchema.multiplex(multiplex_queries, context: context)
|
||||||
end
|
end
|
||||||
|
|
|
@ -32,7 +32,7 @@ class UsersFinder
|
||||||
end
|
end
|
||||||
|
|
||||||
def execute
|
def execute
|
||||||
users = User.all.order_id_desc
|
users = base_scope
|
||||||
users = by_username(users)
|
users = by_username(users)
|
||||||
users = by_id(users)
|
users = by_id(users)
|
||||||
users = by_admins(users)
|
users = by_admins(users)
|
||||||
|
@ -53,6 +53,10 @@ class UsersFinder
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def base_scope
|
||||||
|
User.all.order_id_desc
|
||||||
|
end
|
||||||
|
|
||||||
def by_username(users)
|
def by_username(users)
|
||||||
return users unless params[:username]
|
return users unless params[:username]
|
||||||
|
|
||||||
|
|
|
@ -62,23 +62,29 @@ module ProjectsHelper
|
||||||
name: author.name
|
name: author.name
|
||||||
}
|
}
|
||||||
|
|
||||||
author_html = []
|
inject_classes = ["author-link"]
|
||||||
|
|
||||||
|
if opts[:name]
|
||||||
|
inject_classes.concat(["js-user-link", opts[:extra_class], opts[:mobile_classes]])
|
||||||
|
else
|
||||||
|
inject_classes.append( "has-tooltip" )
|
||||||
|
end
|
||||||
|
|
||||||
|
inject_classes = inject_classes.compact.join(" ")
|
||||||
|
|
||||||
|
author_html = []
|
||||||
# Build avatar image tag
|
# Build avatar image tag
|
||||||
author_html << link_to_member_avatar(author, opts) if opts[:avatar]
|
author_html << link_to_member_avatar(author, opts) if opts[:avatar]
|
||||||
|
|
||||||
# Build name span tag
|
# Build name span tag
|
||||||
author_html << author_content_tag(author, opts) if opts[:name]
|
author_html << author_content_tag(author, opts) if opts[:name]
|
||||||
|
|
||||||
author_html << capture(&block) if block
|
author_html << capture(&block) if block
|
||||||
|
|
||||||
author_html = author_html.join.html_safe
|
author_html = author_html.join.html_safe
|
||||||
|
|
||||||
if opts[:name]
|
if opts[:name]
|
||||||
link_to(author_html, user_path(author), class: "author-link js-user-link #{"#{opts[:extra_class]}" if opts[:extra_class]} #{"#{opts[:mobile_classes]}" if opts[:mobile_classes]}", data: data_attrs).html_safe
|
link_to(author_html, user_path(author), class: inject_classes, data: data_attrs).html_safe
|
||||||
else
|
else
|
||||||
title = opts[:title].sub(":name", sanitize(author.name))
|
title = opts[:title].sub(":name", sanitize(author.name))
|
||||||
link_to(author_html, user_path(author), class: "author-link has-tooltip", title: title, data: { container: 'body', qa_selector: 'assignee_link' }).html_safe
|
link_to(author_html, user_path(author), class: inject_classes, title: title, data: { container: 'body', qa_selector: 'assignee_link' }).html_safe
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/347371
|
||||||
milestone: '14.6'
|
milestone: '14.6'
|
||||||
type: development
|
type: development
|
||||||
group: group::pipeline execution
|
group: group::pipeline execution
|
||||||
default_enabled: false
|
default_enabled: true
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
---
|
||||||
|
name: usage_data_i_code_review_user_jetbrains_api_request
|
||||||
|
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/78713
|
||||||
|
rollout_issue_url:
|
||||||
|
milestone: '14.8'
|
||||||
|
type: development
|
||||||
|
group: group::code review
|
||||||
|
default_enabled: true
|
|
@ -39,6 +39,7 @@ Rails.autoloaders.each do |autoloader|
|
||||||
'hangouts_chat_http_override' => 'HangoutsChatHTTPOverride',
|
'hangouts_chat_http_override' => 'HangoutsChatHTTPOverride',
|
||||||
'chunked_io' => 'ChunkedIO',
|
'chunked_io' => 'ChunkedIO',
|
||||||
'http_io' => 'HttpIO',
|
'http_io' => 'HttpIO',
|
||||||
|
'jetbrains_plugin_activity_unique_counter' => 'JetBrainsPluginActivityUniqueCounter',
|
||||||
'json_formatter' => 'JSONFormatter',
|
'json_formatter' => 'JSONFormatter',
|
||||||
'json_web_token' => 'JSONWebToken',
|
'json_web_token' => 'JSONWebToken',
|
||||||
'as_json' => 'AsJSON',
|
'as_json' => 'AsJSON',
|
||||||
|
|
|
@ -73,6 +73,7 @@
|
||||||
- 'i_code_review_post_merge_click_cherry_pick'
|
- 'i_code_review_post_merge_click_cherry_pick'
|
||||||
- 'i_code_review_post_merge_submit_revert_modal'
|
- 'i_code_review_post_merge_submit_revert_modal'
|
||||||
- 'i_code_review_post_merge_submit_cherry_pick_modal'
|
- 'i_code_review_post_merge_submit_cherry_pick_modal'
|
||||||
|
- 'i_code_review_user_jetbrains_api_request'
|
||||||
- name: code_review_category_monthly_active_users
|
- name: code_review_category_monthly_active_users
|
||||||
operator: OR
|
operator: OR
|
||||||
source: redis
|
source: redis
|
||||||
|
@ -144,3 +145,4 @@
|
||||||
time_frame: [7d, 28d]
|
time_frame: [7d, 28d]
|
||||||
events:
|
events:
|
||||||
- 'i_code_review_user_vs_code_api_request'
|
- 'i_code_review_user_vs_code_api_request'
|
||||||
|
- 'i_code_review_user_jetbrains_api_request'
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
---
|
||||||
|
key_path: redis_hll_counters.code_review.i_code_review_user_jetbrains_api_request_monthly
|
||||||
|
description: Count of unique users per month who use GitLab plugin for JetBrains
|
||||||
|
product_section: dev
|
||||||
|
product_stage: create
|
||||||
|
product_group: group::code review
|
||||||
|
product_category: editor_extension
|
||||||
|
value_type: number
|
||||||
|
status: active
|
||||||
|
milestone: "14.8"
|
||||||
|
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/78713
|
||||||
|
time_frame: 28d
|
||||||
|
data_source: redis_hll
|
||||||
|
data_category: optional
|
||||||
|
instrumentation_class: RedisHLLMetric
|
||||||
|
options:
|
||||||
|
events:
|
||||||
|
- i_code_review_user_jetbrains_api_request
|
||||||
|
performance_indicator_type: []
|
||||||
|
distribution:
|
||||||
|
- ce
|
||||||
|
- ee
|
||||||
|
tier:
|
||||||
|
- free
|
||||||
|
- premium
|
||||||
|
- ultimate
|
|
@ -0,0 +1,26 @@
|
||||||
|
---
|
||||||
|
key_path: redis_hll_counters.code_review.i_code_review_user_jetbrains_api_request_weekly
|
||||||
|
description: Count of unique users per month who use GitLab plugin for JetBrains
|
||||||
|
product_section: dev
|
||||||
|
product_stage: create
|
||||||
|
product_group: group::code review
|
||||||
|
product_category: editor_extension
|
||||||
|
value_type: number
|
||||||
|
status: active
|
||||||
|
milestone: "14.8"
|
||||||
|
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/78713
|
||||||
|
time_frame: 7d
|
||||||
|
data_source: redis_hll
|
||||||
|
data_category: optional
|
||||||
|
instrumentation_class: RedisHLLMetric
|
||||||
|
options:
|
||||||
|
events:
|
||||||
|
- i_code_review_user_jetbrains_api_request
|
||||||
|
performance_indicator_type: []
|
||||||
|
distribution:
|
||||||
|
- ce
|
||||||
|
- ee
|
||||||
|
tier:
|
||||||
|
- free
|
||||||
|
- premium
|
||||||
|
- ultimate
|
|
@ -0,0 +1,18 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class AddUserDetailsProvisioningIndex < Gitlab::Database::Migration[1.0]
|
||||||
|
disable_ddl_transaction!
|
||||||
|
|
||||||
|
INDEX_NAME = 'idx_user_details_on_provisioned_by_group_id_user_id'
|
||||||
|
OLD_INDEX_NAME = 'index_user_details_on_provisioned_by_group_id'
|
||||||
|
|
||||||
|
def up
|
||||||
|
add_concurrent_index :user_details, [:provisioned_by_group_id, :user_id], name: INDEX_NAME
|
||||||
|
remove_concurrent_index_by_name :user_details, OLD_INDEX_NAME
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
add_concurrent_index :user_details, :provisioned_by_group_id, name: OLD_INDEX_NAME
|
||||||
|
remove_concurrent_index_by_name :user_details, INDEX_NAME
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1 @@
|
||||||
|
7a48d49d576d183198df370593642419da5707d8b018a23f541c448e2aa7ad65
|
|
@ -25345,6 +25345,8 @@ CREATE INDEX idx_security_scans_on_scan_type ON security_scans USING btree (scan
|
||||||
|
|
||||||
CREATE UNIQUE INDEX idx_serverless_domain_cluster_on_clusters_applications_knative ON serverless_domain_cluster USING btree (clusters_applications_knative_id);
|
CREATE UNIQUE INDEX idx_serverless_domain_cluster_on_clusters_applications_knative ON serverless_domain_cluster USING btree (clusters_applications_knative_id);
|
||||||
|
|
||||||
|
CREATE INDEX idx_user_details_on_provisioned_by_group_id_user_id ON user_details USING btree (provisioned_by_group_id, user_id);
|
||||||
|
|
||||||
CREATE UNIQUE INDEX idx_vuln_signatures_on_occurrences_id_and_signature_sha ON vulnerability_finding_signatures USING btree (finding_id, signature_sha);
|
CREATE UNIQUE INDEX idx_vuln_signatures_on_occurrences_id_and_signature_sha ON vulnerability_finding_signatures USING btree (finding_id, signature_sha);
|
||||||
|
|
||||||
CREATE UNIQUE INDEX idx_vuln_signatures_uniqueness_signature_sha ON vulnerability_finding_signatures USING btree (finding_id, algorithm_type, signature_sha);
|
CREATE UNIQUE INDEX idx_vuln_signatures_uniqueness_signature_sha ON vulnerability_finding_signatures USING btree (finding_id, algorithm_type, signature_sha);
|
||||||
|
@ -27987,8 +27989,6 @@ CREATE UNIQUE INDEX index_user_details_on_phone ON user_details USING btree (pho
|
||||||
|
|
||||||
COMMENT ON INDEX index_user_details_on_phone IS 'JiHu-specific index';
|
COMMENT ON INDEX index_user_details_on_phone IS 'JiHu-specific index';
|
||||||
|
|
||||||
CREATE INDEX index_user_details_on_provisioned_by_group_id ON user_details USING btree (provisioned_by_group_id);
|
|
||||||
|
|
||||||
CREATE UNIQUE INDEX index_user_details_on_user_id ON user_details USING btree (user_id);
|
CREATE UNIQUE INDEX index_user_details_on_user_id ON user_details USING btree (user_id);
|
||||||
|
|
||||||
CREATE INDEX index_user_group_callouts_on_group_id ON user_group_callouts USING btree (group_id);
|
CREATE INDEX index_user_group_callouts_on_group_id ON user_group_callouts USING btree (group_id);
|
||||||
|
|
|
@ -1548,6 +1548,46 @@ To fix this you can do one of two things:
|
||||||
We use a concrete example to illustrate how to
|
We use a concrete example to illustrate how to
|
||||||
diagnose a problem with the S3 setup.
|
diagnose a problem with the S3 setup.
|
||||||
|
|
||||||
|
#### Investigate a cleanup policy
|
||||||
|
|
||||||
|
If you're unsure why your cleanup policy did or didn't delete a tag, execute the policy line by line
|
||||||
|
by running the below script from the [Rails console](../../administration/operations/rails_console.md).
|
||||||
|
This can help diagnose problems with the policy.
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
repo = ContainerRepository.find(<project_id>)
|
||||||
|
policy = repo.project.container_expiration_policy
|
||||||
|
|
||||||
|
tags = repo.tags
|
||||||
|
tags.map(&:name)
|
||||||
|
|
||||||
|
tags.reject!(&:latest?)
|
||||||
|
tags.map(&:name)
|
||||||
|
|
||||||
|
regex_delete = ::Gitlab::UntrustedRegexp.new("\\A#{policy.name_regex}\\z")
|
||||||
|
regex_retain = ::Gitlab::UntrustedRegexp.new("\\A#{policy.name_regex_keep}\\z")
|
||||||
|
|
||||||
|
tags.select! { |tag| regex_delete.match?(tag.name) && !regex_retain.match?(tag.name) }
|
||||||
|
|
||||||
|
tags.map(&:name)
|
||||||
|
|
||||||
|
now = DateTime.current
|
||||||
|
tags.sort_by! { |tag| tag.created_at || now }.reverse! # Lengthy operation
|
||||||
|
|
||||||
|
tags = tags.drop(policy.keep_n)
|
||||||
|
tags.map(&:name)
|
||||||
|
|
||||||
|
older_than_timestamp = ChronicDuration.parse(policy.older_than).seconds.ago
|
||||||
|
|
||||||
|
tags.select! { |tag| tag.created_at && tag.created_at < older_than_timestamp }
|
||||||
|
|
||||||
|
tags.map(&:name)
|
||||||
|
```
|
||||||
|
|
||||||
|
- The script builds the list of tags to delete (`tags`).
|
||||||
|
- `tags.map(&:name)` prints a list of tags to remove. This may be a lengthy operation.
|
||||||
|
- After each filter, check the list of `tags` to see if it contains the intended tags to destroy.
|
||||||
|
|
||||||
#### Unexpected 403 error during push
|
#### Unexpected 403 error during push
|
||||||
|
|
||||||
A user attempted to enable an S3-backed Registry. The `docker login` step went
|
A user attempted to enable an S3-backed Registry. The `docker login` step went
|
||||||
|
|
|
@ -1523,3 +1523,75 @@ DELETE /groups/:id/push_rule
|
||||||
| Attribute | Type | Required | Description |
|
| Attribute | Type | Required | Description |
|
||||||
| --------- | ---- | -------- | ----------- |
|
| --------- | ---- | -------- | ----------- |
|
||||||
| `id` | integer/string | yes | The ID or [URL-encoded path of the group](index.md#namespaced-path-encoding) |
|
| `id` | integer/string | yes | The ID or [URL-encoded path of the group](index.md#namespaced-path-encoding) |
|
||||||
|
|
||||||
|
## Provisioned users API **(PREMIUM)**
|
||||||
|
|
||||||
|
> Introduced in GitLab 14.8.
|
||||||
|
|
||||||
|
### List provisioned users
|
||||||
|
|
||||||
|
Get a list of users provisioned by a given group. Does not include users provisioned by subgroups.
|
||||||
|
Requires at least the Maintainer role on the group.
|
||||||
|
|
||||||
|
```plaintext
|
||||||
|
GET /group/:provisioned_group_id/provisioned_users
|
||||||
|
```
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
|
||||||
|
| Attribute | Type | Required | Description |
|
||||||
|
|------------------------|----------|----------|-----------------------------------------------|
|
||||||
|
| `provisioned_group_id` | integer | yes | The ID or [URL-encoded path of the group](index.md#namespaced-path-encoding) |
|
||||||
|
| `username` | string | no | Get a single user with a specific username |
|
||||||
|
| `search` | string | no | Filter list by name, email or username |
|
||||||
|
| `active` | boolean | no | Filters only active users |
|
||||||
|
| `blocked` | boolean | no | Filters only blocked users |
|
||||||
|
| `created_after` | datetime | no | Return users created after the specified time |
|
||||||
|
| `created_before` | datetime | no | Return users created before the specified time |
|
||||||
|
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
{
|
||||||
|
id: 66,
|
||||||
|
username: "user22",
|
||||||
|
name: "John Doe22",
|
||||||
|
state: "active",
|
||||||
|
avatar_url: "https://www.gravatar.com/avatar/xxx?s=80&d=identicon",
|
||||||
|
web_url: "http://my.gitlab.com/user22",
|
||||||
|
created_at: "2021-09-10T12:48:22.381Z",
|
||||||
|
bio: "",
|
||||||
|
location: null,
|
||||||
|
public_email: "",
|
||||||
|
skype: "",
|
||||||
|
linkedin: "",
|
||||||
|
twitter: "",
|
||||||
|
website_url: "",
|
||||||
|
organization: null,
|
||||||
|
job_title: "",
|
||||||
|
pronouns: null,
|
||||||
|
bot: false,
|
||||||
|
work_information: null,
|
||||||
|
followers: 0,
|
||||||
|
following: 0,
|
||||||
|
local_time: null,
|
||||||
|
last_sign_in_at: null,
|
||||||
|
confirmed_at: "2021-09-10T12:48:22.330Z",
|
||||||
|
last_activity_on: null,
|
||||||
|
email: "user22@example.org",
|
||||||
|
theme_id: 1,
|
||||||
|
color_scheme_id: 1,
|
||||||
|
projects_limit: 100000,
|
||||||
|
current_sign_in_at: null,
|
||||||
|
identities: [ ],
|
||||||
|
can_create_group: true,
|
||||||
|
can_create_project: true,
|
||||||
|
two_factor_enabled: false,
|
||||||
|
external: false,
|
||||||
|
private_profile: false,
|
||||||
|
commit_email: "user22@example.org",
|
||||||
|
shared_runners_minutes_limit: null,
|
||||||
|
extra_shared_runners_minutes_limit: null
|
||||||
|
},
|
||||||
|
...
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
|
@ -332,10 +332,6 @@ try to preserve worktrees and try to re-use them by default.
|
||||||
|
|
||||||
This has limitations when using the [Docker Machine executor](https://docs.gitlab.com/runner/executors/docker_machine.html).
|
This has limitations when using the [Docker Machine executor](https://docs.gitlab.com/runner/executors/docker_machine.html).
|
||||||
|
|
||||||
It does not work for [the `kubernetes` executor](https://docs.gitlab.com/runner/executors/kubernetes.html),
|
|
||||||
but a [feature proposal](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/3847) exists.
|
|
||||||
The `kubernetes` executor always clones into an temporary directory.
|
|
||||||
|
|
||||||
A Git strategy of `none` also re-uses the local working copy, but skips all Git
|
A Git strategy of `none` also re-uses the local working copy, but skips all Git
|
||||||
operations normally done by GitLab. GitLab Runner pre-clone scripts are also skipped,
|
operations normally done by GitLab. GitLab Runner pre-clone scripts are also skipped,
|
||||||
if present. This strategy could mean you need to add `fetch` and `checkout` commands
|
if present. This strategy could mean you need to add `fetch` and `checkout` commands
|
||||||
|
|
|
@ -76,6 +76,10 @@ module API
|
||||||
Gitlab::UsageDataCounters::VSCodeExtensionActivityUniqueCounter.track_api_request_when_trackable(user_agent: request&.user_agent, user: @current_user)
|
Gitlab::UsageDataCounters::VSCodeExtensionActivityUniqueCounter.track_api_request_when_trackable(user_agent: request&.user_agent, user: @current_user)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
after do
|
||||||
|
Gitlab::UsageDataCounters::JetBrainsPluginActivityUniqueCounter.track_api_request_when_trackable(user_agent: request&.user_agent, user: @current_user)
|
||||||
|
end
|
||||||
|
|
||||||
# The locale is set to the current user's locale when `current_user` is loaded
|
# The locale is set to the current user's locale when `current_user` is loaded
|
||||||
after { Gitlab::I18n.use_default_locale }
|
after { Gitlab::I18n.use_default_locale }
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ module Gitlab
|
||||||
gon.revision = Gitlab.revision
|
gon.revision = Gitlab.revision
|
||||||
gon.feature_category = Gitlab::ApplicationContext.current_context_attribute(:feature_category).presence
|
gon.feature_category = Gitlab::ApplicationContext.current_context_attribute(:feature_category).presence
|
||||||
gon.gitlab_logo = ActionController::Base.helpers.asset_path('gitlab_logo.png')
|
gon.gitlab_logo = ActionController::Base.helpers.asset_path('gitlab_logo.png')
|
||||||
|
gon.secure = Gitlab.config.gitlab.https
|
||||||
gon.sprite_icons = IconsHelper.sprite_icon_path
|
gon.sprite_icons = IconsHelper.sprite_icon_path
|
||||||
gon.sprite_file_icons = IconsHelper.sprite_file_icons_path
|
gon.sprite_file_icons = IconsHelper.sprite_file_icons_path
|
||||||
gon.emoji_sprites_css_path = ActionController::Base.helpers.stylesheet_path('emoji_sprites')
|
gon.emoji_sprites_css_path = ActionController::Base.helpers.stylesheet_path('emoji_sprites')
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Gitlab
|
||||||
|
module UsageDataCounters
|
||||||
|
module JetBrainsPluginActivityUniqueCounter
|
||||||
|
JETBRAINS_API_REQUEST_ACTION = 'i_code_review_user_jetbrains_api_request'
|
||||||
|
JETBRAINS_USER_AGENT_REGEX = /\Agitlab-jetbrains-plugin/.freeze
|
||||||
|
|
||||||
|
class << self
|
||||||
|
def track_api_request_when_trackable(user_agent:, user:)
|
||||||
|
user_agent&.match?(JETBRAINS_USER_AGENT_REGEX) && track_unique_action_by_user(JETBRAINS_API_REQUEST_ACTION, user)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def track_unique_action_by_user(action, user)
|
||||||
|
return unless user
|
||||||
|
|
||||||
|
track_unique_action(action, user.id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def track_unique_action(action, value)
|
||||||
|
Gitlab::UsageDataCounters::HLLRedisCounter.track_usage_event(action, value)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -127,6 +127,11 @@
|
||||||
redis_slot: code_review
|
redis_slot: code_review
|
||||||
category: code_review
|
category: code_review
|
||||||
aggregation: weekly
|
aggregation: weekly
|
||||||
|
- name: i_code_review_user_jetbrains_api_request
|
||||||
|
redis_slot: code_review
|
||||||
|
category: code_review
|
||||||
|
aggregation: weekly
|
||||||
|
feature_flag: usage_data_i_code_review_user_jetbrains_api_request
|
||||||
- name: i_code_review_user_create_mr_from_issue
|
- name: i_code_review_user_create_mr_from_issue
|
||||||
redis_slot: code_review
|
redis_slot: code_review
|
||||||
category: code_review
|
category: code_review
|
||||||
|
|
3
qa/qa.rb
3
qa/qa.rb
|
@ -51,7 +51,8 @@ module QA
|
||||||
"smtp" => "SMTP",
|
"smtp" => "SMTP",
|
||||||
"otp" => "OTP",
|
"otp" => "OTP",
|
||||||
"jira_api" => "JiraAPI",
|
"jira_api" => "JiraAPI",
|
||||||
"registry_tls" => "RegistryTLS"
|
"registry_tls" => "RegistryTLS",
|
||||||
|
"jetbrains" => "JetBrains"
|
||||||
)
|
)
|
||||||
|
|
||||||
loader.setup
|
loader.setup
|
||||||
|
|
|
@ -58,7 +58,7 @@ module QA
|
||||||
{
|
{
|
||||||
title: "Reliable e2e test report",
|
title: "Reliable e2e test report",
|
||||||
description: report_issue_body,
|
description: report_issue_body,
|
||||||
labels: "Quality,test,type::maintenance,reliable test report"
|
labels: "Quality,test,type::maintenance,reliable test report,automation:devops-mapping-disable"
|
||||||
},
|
},
|
||||||
headers: { "PRIVATE-TOKEN" => gitlab_access_token }
|
headers: { "PRIVATE-TOKEN" => gitlab_access_token }
|
||||||
)
|
)
|
||||||
|
|
|
@ -167,7 +167,7 @@ describe QA::Tools::ReliableReport do
|
||||||
payload: {
|
payload: {
|
||||||
title: "Reliable e2e test report",
|
title: "Reliable e2e test report",
|
||||||
description: issue_body,
|
description: issue_body,
|
||||||
labels: "Quality,test,type::maintenance,reliable test report"
|
labels: "Quality,test,type::maintenance,reliable test report,automation:devops-mapping-disable"
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
expect(slack_notifier).to have_received(:post).with(
|
expect(slack_notifier).to have_received(:post).with(
|
||||||
|
|
|
@ -124,6 +124,16 @@ RSpec.describe GraphqlController do
|
||||||
|
|
||||||
post :execute
|
post :execute
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'calls the track jetbrains api when trackable method' do
|
||||||
|
agent = 'gitlab-jetbrains-plugin/0.0.1 intellij-idea/2021.2.4 java/11.0.13 mac-os-x/aarch64/12.1'
|
||||||
|
request.env['HTTP_USER_AGENT'] = agent
|
||||||
|
|
||||||
|
expect(Gitlab::UsageDataCounters::JetBrainsPluginActivityUniqueCounter)
|
||||||
|
.to receive(:track_api_request_when_trackable).with(user_agent: agent, user: user)
|
||||||
|
|
||||||
|
post :execute
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when user uses an API token' do
|
context 'when user uses an API token' do
|
||||||
|
@ -151,6 +161,16 @@ RSpec.describe GraphqlController do
|
||||||
|
|
||||||
subject
|
subject
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'calls the track jetbrains api when trackable method' do
|
||||||
|
agent = 'gitlab-jetbrains-plugin/0.0.1 intellij-idea/2021.2.4 java/11.0.13 mac-os-x/aarch64/12.1'
|
||||||
|
request.env['HTTP_USER_AGENT'] = agent
|
||||||
|
|
||||||
|
expect(Gitlab::UsageDataCounters::JetBrainsPluginActivityUniqueCounter)
|
||||||
|
.to receive(:track_api_request_when_trackable).with(user_agent: agent, user: user)
|
||||||
|
|
||||||
|
subject
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when user is not logged in' do
|
context 'when user is not logged in' do
|
||||||
|
|
|
@ -30,6 +30,7 @@ describe('broadcast message on dismiss', () => {
|
||||||
|
|
||||||
expect(Cookies.set).toHaveBeenCalledWith('hide_broadcast_message_1', true, {
|
expect(Cookies.set).toHaveBeenCalledWith('hide_broadcast_message_1', true, {
|
||||||
expires: new Date(endsAt),
|
expires: new Date(endsAt),
|
||||||
|
secure: false,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -118,7 +118,7 @@ describe('When the code_quality_walkthrough URL parameter is present', () => {
|
||||||
expect(Cookies.set).toHaveBeenCalledWith(
|
expect(Cookies.set).toHaveBeenCalledWith(
|
||||||
EXPERIMENT_NAME,
|
EXPERIMENT_NAME,
|
||||||
{ commit_ci_file: true, data: dummyContext },
|
{ commit_ci_file: true, data: dummyContext },
|
||||||
{ expires: 365 },
|
{ expires: 365, secure: false },
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -254,7 +254,10 @@ describe('Design management design sidebar component', () => {
|
||||||
it(`sets a ${cookieKey} cookie on clicking outside the popover`, () => {
|
it(`sets a ${cookieKey} cookie on clicking outside the popover`, () => {
|
||||||
jest.spyOn(Cookies, 'set');
|
jest.spyOn(Cookies, 'set');
|
||||||
wrapper.trigger('click');
|
wrapper.trigger('click');
|
||||||
expect(Cookies.set).toHaveBeenCalledWith(cookieKey, 'true', { expires: 365 * 10 });
|
expect(Cookies.set).toHaveBeenCalledWith(cookieKey, 'true', {
|
||||||
|
expires: 365 * 10,
|
||||||
|
secure: false,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ describe('addToFrequentlyUsed', () => {
|
||||||
|
|
||||||
expect(Cookies.set).toHaveBeenCalledWith('frequently_used_emojis', 'thumbsup', {
|
expect(Cookies.set).toHaveBeenCalledWith('frequently_used_emojis', 'thumbsup', {
|
||||||
expires: 365,
|
expires: 365,
|
||||||
|
secure: false,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -41,6 +42,7 @@ describe('addToFrequentlyUsed', () => {
|
||||||
|
|
||||||
expect(Cookies.set).toHaveBeenCalledWith('frequently_used_emojis', 'thumbsdown,thumbsup', {
|
expect(Cookies.set).toHaveBeenCalledWith('frequently_used_emojis', 'thumbsdown,thumbsup', {
|
||||||
expires: 365,
|
expires: 365,
|
||||||
|
secure: false,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -51,6 +53,7 @@ describe('addToFrequentlyUsed', () => {
|
||||||
|
|
||||||
expect(Cookies.set).toHaveBeenCalledWith('frequently_used_emojis', 'thumbsup', {
|
expect(Cookies.set).toHaveBeenCalledWith('frequently_used_emojis', 'thumbsup', {
|
||||||
expires: 365,
|
expires: 365,
|
||||||
|
secure: false,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -159,7 +159,10 @@ describe('Landing', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should call Cookies.set', () => {
|
it('should call Cookies.set', () => {
|
||||||
expect(Cookies.set).toHaveBeenCalledWith(test.cookieName, 'true', { expires: 365 });
|
expect(Cookies.set).toHaveBeenCalledWith(test.cookieName, 'true', {
|
||||||
|
expires: 365,
|
||||||
|
secure: false,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -207,7 +207,10 @@ describe('merge conflicts actions', () => {
|
||||||
],
|
],
|
||||||
[],
|
[],
|
||||||
() => {
|
() => {
|
||||||
expect(Cookies.set).toHaveBeenCalledWith('diff_view', payload);
|
expect(Cookies.set).toHaveBeenCalledWith('diff_view', payload, {
|
||||||
|
expires: 365,
|
||||||
|
secure: false,
|
||||||
|
});
|
||||||
done();
|
done();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
|
@ -84,6 +84,7 @@ describe('Pipeline Schedule Callout', () => {
|
||||||
|
|
||||||
expect(setCookiesSpy).toHaveBeenCalledWith('pipeline_schedules_callout_dismissed', true, {
|
expect(setCookiesSpy).toHaveBeenCalledWith('pipeline_schedules_callout_dismissed', true, {
|
||||||
expires: 365,
|
expires: 365,
|
||||||
|
secure: false,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -37,7 +37,10 @@ describe('Knative survey banner', () => {
|
||||||
wrapper.find(GlBanner).vm.$emit('close');
|
wrapper.find(GlBanner).vm.$emit('close');
|
||||||
|
|
||||||
await nextTick();
|
await nextTick();
|
||||||
expect(Cookies.set).toHaveBeenCalledWith('hide_serverless_survey', 'true', { expires: 3650 });
|
expect(Cookies.set).toHaveBeenCalledWith('hide_serverless_survey', 'true', {
|
||||||
|
expires: 3650,
|
||||||
|
secure: false,
|
||||||
|
});
|
||||||
expect(wrapper.find(GlBanner).exists()).toBe(false);
|
expect(wrapper.find(GlBanner).exists()).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,10 @@ describe('IssuableSidebarRoot', () => {
|
||||||
it('updates "collapsed_gutter" cookie value and layout classes', async () => {
|
it('updates "collapsed_gutter" cookie value and layout classes', async () => {
|
||||||
await findToggleSidebarButton().trigger('click');
|
await findToggleSidebarButton().trigger('click');
|
||||||
|
|
||||||
expect(Cookies.set).toHaveBeenCalledWith(USER_COLLAPSED_GUTTER_COOKIE, true);
|
expect(Cookies.set).toHaveBeenCalledWith(USER_COLLAPSED_GUTTER_COOKIE, true, {
|
||||||
|
expires: 365,
|
||||||
|
secure: false,
|
||||||
|
});
|
||||||
assertPageLayoutClasses({ isExpanded: false });
|
assertPageLayoutClasses({ isExpanded: false });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -6,9 +6,41 @@ RSpec.describe Gitlab::GonHelper do
|
||||||
let(:helper) do
|
let(:helper) do
|
||||||
Class.new do
|
Class.new do
|
||||||
include Gitlab::GonHelper
|
include Gitlab::GonHelper
|
||||||
|
|
||||||
|
def current_user
|
||||||
|
nil
|
||||||
|
end
|
||||||
end.new
|
end.new
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '#add_gon_variables' do
|
||||||
|
let(:gon) { double('gon').as_null_object }
|
||||||
|
let(:https) { true }
|
||||||
|
|
||||||
|
before do
|
||||||
|
allow(helper).to receive(:gon).and_return(gon)
|
||||||
|
stub_config_setting(https: https)
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when HTTPS is enabled' do
|
||||||
|
it 'sets the secure flag to true' do
|
||||||
|
expect(gon).to receive(:secure=).with(true)
|
||||||
|
|
||||||
|
helper.add_gon_variables
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when HTTP is enabled' do
|
||||||
|
let(:https) { false }
|
||||||
|
|
||||||
|
it 'sets the secure flag to false' do
|
||||||
|
expect(gon).to receive(:secure=).with(false)
|
||||||
|
|
||||||
|
helper.add_gon_variables
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe '#push_frontend_feature_flag' do
|
describe '#push_frontend_feature_flag' do
|
||||||
before do
|
before do
|
||||||
skip_feature_flags_yaml_validation
|
skip_feature_flags_yaml_validation
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
RSpec.shared_examples 'a tracked jetbrains unique action' do |event|
|
||||||
|
before do
|
||||||
|
stub_application_setting(usage_ping_enabled: true)
|
||||||
|
end
|
||||||
|
|
||||||
|
def count_unique(date_from:, date_to:)
|
||||||
|
Gitlab::UsageDataCounters::HLLRedisCounter.unique_events(event_names: action, start_date: date_from, end_date: date_to)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'tracks when the user agent is from jetbrains' do
|
||||||
|
aggregate_failures do
|
||||||
|
user_agent = { user_agent: 'gitlab-jetbrains-plugin/0.0.1 intellij-idea/2021.2.4 java/11.0.13 mac-os-x/aarch64/12.1' }
|
||||||
|
|
||||||
|
expect(track_action(user: user1, **user_agent)).to be_truthy
|
||||||
|
expect(track_action(user: user1, **user_agent)).to be_truthy
|
||||||
|
expect(track_action(user: user2, **user_agent)).to be_truthy
|
||||||
|
|
||||||
|
expect(count_unique(date_from: time - 1.week, date_to: time + 1.week)).to eq(2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'does not track when the user agent is not from jetbrains' do
|
||||||
|
aggregate_failures do
|
||||||
|
user_agent = { user_agent: 'normal_user_agent' }
|
||||||
|
|
||||||
|
expect(track_action(user: user1, **user_agent)).to be_falsey
|
||||||
|
expect(track_action(user: user1, **user_agent)).to be_falsey
|
||||||
|
expect(track_action(user: user2, **user_agent)).to be_falsey
|
||||||
|
|
||||||
|
expect(count_unique(date_from: time - 1.week, date_to: time + 1.week)).to eq(0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'does not track if user agent is not present' do
|
||||||
|
expect(track_action(user: nil, user_agent: nil)).to be_nil
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'does not track if user is not present' do
|
||||||
|
user_agent = { user_agent: 'gitlab-jetbrains-plugin/0.0.1 intellij-idea/2021.2.4 java/11.0.13 mac-os-x/aarch64/12.1' }
|
||||||
|
|
||||||
|
expect(track_action(user: nil, **user_agent)).to be_nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
RSpec.describe Gitlab::UsageDataCounters::JetBrainsPluginActivityUniqueCounter, :clean_gitlab_redis_shared_state do
|
||||||
|
let(:user1) { build(:user, id: 1) }
|
||||||
|
let(:user2) { build(:user, id: 2) }
|
||||||
|
let(:time) { Time.current }
|
||||||
|
|
||||||
|
context 'when tracking a jetbrains api request' do
|
||||||
|
it_behaves_like 'a tracked jetbrains unique action' do
|
||||||
|
let(:action) { described_class::JETBRAINS_API_REQUEST_ACTION }
|
||||||
|
|
||||||
|
def track_action(params)
|
||||||
|
described_class.track_api_request_when_trackable(**params)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -3,11 +3,11 @@
|
||||||
RSpec.shared_examples 'group and project packages query' do
|
RSpec.shared_examples 'group and project packages query' do
|
||||||
include GraphqlHelpers
|
include GraphqlHelpers
|
||||||
|
|
||||||
let_it_be(:versionaless_package) { create(:maven_package, project: project1, version: nil) }
|
let_it_be(:versionless_package) { create(:maven_package, project: project1, version: nil) }
|
||||||
let_it_be(:maven_package) { create(:maven_package, project: project1, name: 'tab', version: '4.0.0', created_at: 5.days.ago) }
|
let_it_be(:maven_package) { create(:maven_package, project: project1, name: 'bab', version: '6.0.0', created_at: 1.day.ago) }
|
||||||
let_it_be(:package) { create(:npm_package, project: project1, name: 'uab', version: '5.0.0', created_at: 4.days.ago) }
|
let_it_be(:npm_package) { create(:npm_package, project: project1, name: 'cab', version: '7.0.0', created_at: 4.days.ago) }
|
||||||
let_it_be(:composer_package) { create(:composer_package, project: project2, name: 'vab', version: '6.0.0', created_at: 3.days.ago) }
|
let_it_be(:composer_package) { create(:composer_package, project: project2, name: 'dab', version: '4.0.0', created_at: 3.days.ago) }
|
||||||
let_it_be(:debian_package) { create(:debian_package, project: project2, name: 'zab', version: '7.0.0', created_at: 2.days.ago) }
|
let_it_be(:debian_package) { create(:debian_package, project: project2, name: 'aab', version: '5.0.0', created_at: 2.days.ago) }
|
||||||
let_it_be(:composer_metadatum) do
|
let_it_be(:composer_metadatum) do
|
||||||
create(:composer_metadatum, package: composer_package,
|
create(:composer_metadatum, package: composer_package,
|
||||||
target_sha: 'afdeh',
|
target_sha: 'afdeh',
|
||||||
|
@ -21,11 +21,11 @@ RSpec.shared_examples 'group and project packages query' do
|
||||||
|
|
||||||
let(:fields) do
|
let(:fields) do
|
||||||
<<~QUERY
|
<<~QUERY
|
||||||
count
|
count
|
||||||
nodes {
|
nodes {
|
||||||
#{all_graphql_fields_for('packages'.classify, excluded: ['project'])}
|
#{all_graphql_fields_for('packages'.classify, excluded: ['project'])}
|
||||||
metadata { #{query_graphql_fragment('ComposerMetadata')} }
|
metadata { #{query_graphql_fragment('ComposerMetadata')} }
|
||||||
}
|
}
|
||||||
QUERY
|
QUERY
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ RSpec.shared_examples 'group and project packages query' do
|
||||||
|
|
||||||
it 'returns packages successfully' do
|
it 'returns packages successfully' do
|
||||||
expect(package_names).to contain_exactly(
|
expect(package_names).to contain_exactly(
|
||||||
package.name,
|
npm_package.name,
|
||||||
maven_package.name,
|
maven_package.name,
|
||||||
debian_package.name,
|
debian_package.name,
|
||||||
composer_package.name
|
composer_package.name
|
||||||
|
@ -88,7 +88,23 @@ RSpec.shared_examples 'group and project packages query' do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'sorting and pagination' do
|
describe 'sorting and pagination' do
|
||||||
let_it_be(:ascending_packages) { [maven_package, package, composer_package, debian_package].map { |package| global_id_of(package)} }
|
let_it_be(:packages_order_map) do
|
||||||
|
{
|
||||||
|
TYPE_ASC: [maven_package, npm_package, composer_package, debian_package],
|
||||||
|
TYPE_DESC: [debian_package, composer_package, npm_package, maven_package],
|
||||||
|
|
||||||
|
NAME_ASC: [debian_package, maven_package, npm_package, composer_package],
|
||||||
|
NAME_DESC: [composer_package, npm_package, maven_package, debian_package],
|
||||||
|
|
||||||
|
VERSION_ASC: [composer_package, debian_package, maven_package, npm_package],
|
||||||
|
VERSION_DESC: [npm_package, maven_package, debian_package, composer_package],
|
||||||
|
|
||||||
|
CREATED_ASC: [npm_package, composer_package, debian_package, maven_package],
|
||||||
|
CREATED_DESC: [maven_package, debian_package, composer_package, npm_package]
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:expected_packages) { sorted_packages.map { |package| global_id_of(package) } }
|
||||||
|
|
||||||
let(:data_path) { [resource_type, :packages] }
|
let(:data_path) { [resource_type, :packages] }
|
||||||
|
|
||||||
|
@ -96,22 +112,14 @@ RSpec.shared_examples 'group and project packages query' do
|
||||||
resource.add_reporter(current_user)
|
resource.add_reporter(current_user)
|
||||||
end
|
end
|
||||||
|
|
||||||
[:CREATED_ASC, :NAME_ASC, :VERSION_ASC, :TYPE_ASC].each do |order|
|
[:CREATED_ASC, :NAME_ASC, :VERSION_ASC, :TYPE_ASC, :CREATED_DESC, :NAME_DESC, :VERSION_DESC, :TYPE_DESC].each do |order|
|
||||||
context "#{order}" do
|
context "#{order}" do
|
||||||
it_behaves_like 'sorted paginated query' do
|
let(:sorted_packages) { packages_order_map.fetch(order) }
|
||||||
let(:sort_param) { order }
|
|
||||||
let(:first_param) { 4 }
|
|
||||||
let(:all_records) { ascending_packages }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
[:CREATED_DESC, :NAME_DESC, :VERSION_DESC, :TYPE_DESC].each do |order|
|
|
||||||
context "#{order}" do
|
|
||||||
it_behaves_like 'sorted paginated query' do
|
it_behaves_like 'sorted paginated query' do
|
||||||
let(:sort_param) { order }
|
let(:sort_param) { order }
|
||||||
let(:first_param) { 4 }
|
let(:first_param) { 4 }
|
||||||
let(:all_records) { ascending_packages.reverse }
|
let(:all_records) { expected_packages }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -180,7 +188,7 @@ RSpec.shared_examples 'group and project packages query' do
|
||||||
context 'include_versionless' do
|
context 'include_versionless' do
|
||||||
let(:params) { { include_versionless: true } }
|
let(:params) { { include_versionless: true } }
|
||||||
|
|
||||||
it { is_expected.to include({ "name" => versionaless_package.name }) }
|
it { is_expected.to include({ "name" => versionless_package.name }) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue