Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
c2114645bb
commit
dc66c37ac3
|
|
@ -1,5 +1,4 @@
|
|||
---
|
||||
Gitlab/TokenWithoutPrefix:
|
||||
Details: grace period
|
||||
Exclude:
|
||||
- 'app/models/application_setting.rb'
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ export default {
|
|||
<template #head(lastUsedAt)="{ label }">
|
||||
<span>{{ label }}</span>
|
||||
<gl-link :href="$options.lastUsedHelpLink"
|
||||
><gl-icon name="question-o" /><span class="gl-sr-only">{{
|
||||
><gl-icon name="question-o" class="gl-ml-2" /><span class="gl-sr-only">{{
|
||||
s__('AccessTokens|The last time a token was used')
|
||||
}}</span></gl-link
|
||||
>
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ import AlertStatus from '~/vue_shared/alert_details/components/alert_status.vue'
|
|||
import { TOKEN_TYPE_ASSIGNEE } from '~/vue_shared/components/filtered_search_bar/constants';
|
||||
import {
|
||||
tdClass,
|
||||
thClass,
|
||||
bodyTrClass,
|
||||
initialPaginationState,
|
||||
} from '~/vue_shared/components/paginated_table_with_search_and_tabs/constants';
|
||||
|
|
@ -53,7 +52,8 @@ export default {
|
|||
{
|
||||
key: 'severity',
|
||||
label: s__('AlertManagement|Severity'),
|
||||
thClass: `${thClass} gl-w-eighth`,
|
||||
variant: 'secondary',
|
||||
thClass: `gl-w-eighth`,
|
||||
thAttr: TH_TEST_ID,
|
||||
tdClass: `${tdClass} rounded-top text-capitalize sortable-cell`,
|
||||
sortable: true,
|
||||
|
|
@ -61,7 +61,8 @@ export default {
|
|||
{
|
||||
key: 'startedAt',
|
||||
label: s__('AlertManagement|Start time'),
|
||||
thClass: `${thClass} js-started-at w-15p`,
|
||||
variant: 'secondary',
|
||||
thClass: `js-started-at w-15p`,
|
||||
tdClass: `${tdClass} sortable-cell`,
|
||||
sortable: true,
|
||||
},
|
||||
|
|
@ -74,8 +75,8 @@ export default {
|
|||
{
|
||||
key: 'eventCount',
|
||||
label: s__('AlertManagement|Events'),
|
||||
thClass: `${thClass} text-right gl-w-12`,
|
||||
tdClass: `${tdClass} text-md-right sortable-cell`,
|
||||
variant: 'secondary',
|
||||
tdClass: `${tdClass} sortable-cell`,
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
|
|
@ -93,7 +94,8 @@ export default {
|
|||
{
|
||||
key: 'status',
|
||||
label: s__('AlertManagement|Status'),
|
||||
thClass: `${thClass} w-15p`,
|
||||
variant: 'secondary',
|
||||
thClass: `w-15p`,
|
||||
tdClass: `${tdClass} rounded-bottom sortable-cell`,
|
||||
sortable: true,
|
||||
},
|
||||
|
|
@ -329,8 +331,10 @@ export default {
|
|||
:sort-direction="sortDirection"
|
||||
:sort-desc.sync="sortDesc"
|
||||
:sort-by.sync="sortBy"
|
||||
sort-icon-left
|
||||
fixed
|
||||
hover
|
||||
selectable
|
||||
selected-variant="primary"
|
||||
@row-clicked="navigateToAlertDetails"
|
||||
@sort-changed="fetchSortedData"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -211,7 +211,7 @@ export default {
|
|||
>
|
||||
<template v-if="stageCount" #head(title)="data">
|
||||
<span>{{ data.label }}</span
|
||||
><gl-badge class="gl-ml-2" size="sm"
|
||||
><gl-badge class="gl-ml-3" size="sm"
|
||||
><formatted-stage-count :stage-count="stageCount"
|
||||
/></gl-badge>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -269,7 +269,6 @@ export default {
|
|||
stacked="md"
|
||||
fixed
|
||||
show-empty
|
||||
sort-icon-left
|
||||
no-sort-reset
|
||||
no-local-sorting
|
||||
@sort-changed="(val) => $emit('sort-changed', val)"
|
||||
|
|
|
|||
|
|
@ -238,7 +238,6 @@ export default {
|
|||
stacked="md"
|
||||
table-class="text-secondary"
|
||||
show-empty
|
||||
sort-icon-left
|
||||
no-sort-reset
|
||||
:empty-text="$options.i18n.noFilesMessage"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -231,7 +231,6 @@ export default {
|
|||
sort-by="createdAt"
|
||||
show-empty
|
||||
no-local-sorting
|
||||
sort-icon-left
|
||||
fixed
|
||||
@sort-changed="fetchSortedData"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -222,7 +222,6 @@ export default {
|
|||
sort-by="createdAt"
|
||||
show-empty
|
||||
no-local-sorting
|
||||
sort-icon-left
|
||||
fixed
|
||||
@sort-changed="fetchSortedData"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -1,41 +0,0 @@
|
|||
import Vue from 'vue';
|
||||
import { parseBoolean } from '~/lib/utils/common_utils';
|
||||
import ForksButton from './components/forks_button.vue';
|
||||
|
||||
const initForksButton = () => {
|
||||
const el = document.getElementById('js-forks-button');
|
||||
|
||||
if (!el) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const {
|
||||
forksCount,
|
||||
projectFullPath,
|
||||
projectForksUrl,
|
||||
userForkUrl,
|
||||
newForkUrl,
|
||||
canReadCode,
|
||||
canCreateFork,
|
||||
canForkProject,
|
||||
} = el.dataset;
|
||||
|
||||
return new Vue({
|
||||
el,
|
||||
provide: {
|
||||
forksCount,
|
||||
projectFullPath,
|
||||
projectForksUrl,
|
||||
userForkUrl,
|
||||
newForkUrl,
|
||||
canReadCode: parseBoolean(canReadCode),
|
||||
canCreateFork: parseBoolean(canCreateFork),
|
||||
canForkProject: parseBoolean(canForkProject),
|
||||
},
|
||||
render(createElement) {
|
||||
return createElement(ForksButton);
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
export default initForksButton;
|
||||
|
|
@ -23,7 +23,7 @@ export default {
|
|||
},
|
||||
inject: [
|
||||
'isGroup',
|
||||
'id',
|
||||
'groupOrProjectId',
|
||||
'leavePath',
|
||||
'leaveConfirmMessage',
|
||||
'withdrawPath',
|
||||
|
|
@ -90,7 +90,7 @@ export default {
|
|||
},
|
||||
copyIdItem() {
|
||||
return {
|
||||
text: sprintf(this.copyTitle, { id: this.id }),
|
||||
text: sprintf(this.copyTitle, { id: this.groupOrProjectId }),
|
||||
action: () => {
|
||||
this.$toast.show(this.copiedToClipboard);
|
||||
},
|
||||
|
|
@ -148,7 +148,11 @@ export default {
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<gl-disclosure-dropdown-item v-if="id" :item="copyIdItem" :data-clipboard-text="id" />
|
||||
<gl-disclosure-dropdown-item
|
||||
v-if="groupOrProjectId"
|
||||
:item="copyIdItem"
|
||||
:data-clipboard-text="groupOrProjectId"
|
||||
/>
|
||||
|
||||
<gl-disclosure-dropdown-group v-if="hasPath" bordered>
|
||||
<gl-disclosure-dropdown-item v-if="leavePath" ref="leaveItem" :item="leaveItem" />
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ export default function InitMoreActionsDropdown() {
|
|||
name: 'MoreActionsDropdownRoot',
|
||||
provide: {
|
||||
isGroup: parseBoolean(isGroup),
|
||||
id,
|
||||
groupOrProjectId: id,
|
||||
leavePath,
|
||||
leaveConfirmMessage,
|
||||
withdrawPath,
|
||||
|
|
|
|||
|
|
@ -45,12 +45,17 @@ export default {
|
|||
required: false,
|
||||
default: null,
|
||||
},
|
||||
fullPath: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: null,
|
||||
},
|
||||
},
|
||||
|
||||
computed: {
|
||||
title() {
|
||||
return sprintf(s__('BulkImport|Items that failed to be imported for %{id}'), {
|
||||
id: this.entityId,
|
||||
id: this.fullPath || this.entityId,
|
||||
});
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ import SeverityToken from '~/sidebar/components/severity/severity.vue';
|
|||
import Tracking from '~/tracking';
|
||||
import {
|
||||
tdClass,
|
||||
thClass,
|
||||
bodyTrClass,
|
||||
initialPaginationState,
|
||||
} from '~/vue_shared/components/paginated_table_with_search_and_tabs/constants';
|
||||
|
|
@ -54,7 +53,8 @@ export default {
|
|||
{
|
||||
key: 'severity',
|
||||
label: s__('IncidentManagement|Severity'),
|
||||
thClass: `${thClass} gl-w-15p`,
|
||||
variant: 'secondary',
|
||||
thClass: `gl-w-15p`,
|
||||
tdClass: `${tdClass} sortable-cell`,
|
||||
actualSortKey: 'SEVERITY',
|
||||
sortable: true,
|
||||
|
|
@ -69,7 +69,8 @@ export default {
|
|||
{
|
||||
key: 'escalationStatus',
|
||||
label: s__('IncidentManagement|Status'),
|
||||
thClass: `${thClass} gl-w-eighth`,
|
||||
variant: 'secondary',
|
||||
thClass: `gl-w-eighth`,
|
||||
tdClass: `${tdClass} sortable-cell`,
|
||||
actualSortKey: 'ESCALATION_STATUS',
|
||||
sortable: true,
|
||||
|
|
@ -78,7 +79,8 @@ export default {
|
|||
{
|
||||
key: 'createdAt',
|
||||
label: s__('IncidentManagement|Date created'),
|
||||
thClass: `${thClass} gl-w-eighth`,
|
||||
variant: 'secondary',
|
||||
thClass: `gl-w-eighth`,
|
||||
tdClass: `${tdClass} sortable-cell`,
|
||||
actualSortKey: 'CREATED',
|
||||
sortable: true,
|
||||
|
|
@ -87,7 +89,8 @@ export default {
|
|||
{
|
||||
key: 'incidentSla',
|
||||
label: s__('IncidentManagement|Time to SLA'),
|
||||
thClass: `${thClass} gl-text-right gl-w-10p`,
|
||||
variant: 'secondary',
|
||||
thClass: `gl-text-right gl-w-10p`,
|
||||
tdClass: `${tdClass} gl-text-right`,
|
||||
thAttr: TH_INCIDENT_SLA_TEST_ID,
|
||||
actualSortKey: 'SLA_DUE_AT',
|
||||
|
|
@ -102,7 +105,8 @@ export default {
|
|||
{
|
||||
key: 'published',
|
||||
label: s__('IncidentManagement|Published'),
|
||||
thClass: `${thClass} gl-w-15`,
|
||||
variant: 'secondary',
|
||||
thClass: `gl-w-15`,
|
||||
tdClass: `${tdClass} sortable-cell`,
|
||||
actualSortKey: 'PUBLISHED',
|
||||
sortable: true,
|
||||
|
|
@ -388,8 +392,10 @@ export default {
|
|||
sort-by="createdAt"
|
||||
show-empty
|
||||
no-local-sorting
|
||||
sort-icon-left
|
||||
fixed
|
||||
hover
|
||||
selectable
|
||||
selected-variant="primary"
|
||||
@row-clicked="navigateToIncidentDetails"
|
||||
@sort-changed="fetchSortedData"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ export default {
|
|||
containerClass: {
|
||||
default: '',
|
||||
},
|
||||
disabled: {
|
||||
emailsDisabled: {
|
||||
default: false,
|
||||
},
|
||||
dropdownItems: {
|
||||
|
|
@ -81,7 +81,7 @@ export default {
|
|||
this.$options.i18n.notificationTitles[this.selectedNotificationLevel] ||
|
||||
this.selectedNotificationLevel;
|
||||
|
||||
return this.disabled
|
||||
return this.emailsDisabled
|
||||
? this.$options.i18n.notificationDescriptions.owner_disabled
|
||||
: sprintf(this.$options.i18n.notificationTooltipTitle, {
|
||||
notification_title: notificationTitle,
|
||||
|
|
@ -127,7 +127,7 @@ export default {
|
|||
:size="buttonSize"
|
||||
:icon="buttonIcon"
|
||||
:loading="isLoading"
|
||||
:disabled="disabled"
|
||||
:disabled="emailsDisabled"
|
||||
:split="isCustomNotification"
|
||||
:text="buttonText"
|
||||
:no-flip="noFlip"
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ export default () => {
|
|||
provide: {
|
||||
containerClass,
|
||||
buttonSize,
|
||||
disabled: parseBoolean(disabled),
|
||||
emailsDisabled: parseBoolean(disabled),
|
||||
dropdownItems: JSON.parse(dropdownItems),
|
||||
initialNotificationLevel: notificationLevel,
|
||||
helpPagePath,
|
||||
|
|
|
|||
|
|
@ -1,10 +1,16 @@
|
|||
#import "~/graphql_shared/fragments/page_info.fragment.graphql"
|
||||
#import "../fragments/organization.fragment.graphql"
|
||||
|
||||
query getCurrentUserOrganizations($first: Int, $last: Int, $before: String, $after: String) {
|
||||
query getCurrentUserOrganizations(
|
||||
$search: String
|
||||
$first: Int
|
||||
$last: Int
|
||||
$before: String
|
||||
$after: String
|
||||
) {
|
||||
currentUser {
|
||||
id
|
||||
organizations(first: $first, last: $last, before: $before, after: $after) {
|
||||
organizations(search: $search, first: $first, last: $last, before: $before, after: $after) {
|
||||
nodes {
|
||||
...Organization
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,9 @@ export default {
|
|||
createdByPipelineText: s__(
|
||||
'PackageRegistry|Built by pipeline %{link} triggered %{datetime} by %{author}',
|
||||
),
|
||||
publishText: s__('PackageRegistry|Published to the %{project} Package Registry %{datetime}'),
|
||||
publishText: s__(
|
||||
'PackageRegistry|Published to the %{project} Terraform Module Registry %{datetime}',
|
||||
),
|
||||
combinedUpdateText: s__(
|
||||
'PackageRegistry|Package updated by commit %{link} on branch %{branch}, built by pipeline %{pipeline}, and published to the registry %{datetime}',
|
||||
),
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ export const initBulkImportDetails = () => {
|
|||
return null;
|
||||
}
|
||||
|
||||
const { id, entityId } = el.dataset;
|
||||
const { id, entityId, fullPath } = el.dataset;
|
||||
|
||||
return new Vue({
|
||||
el,
|
||||
|
|
@ -18,6 +18,7 @@ export const initBulkImportDetails = () => {
|
|||
props: {
|
||||
id,
|
||||
entityId,
|
||||
fullPath,
|
||||
},
|
||||
});
|
||||
},
|
||||
|
|
|
|||
|
|
@ -0,0 +1,61 @@
|
|||
<script>
|
||||
import { s__, sprintf } from '~/locale';
|
||||
import { isLoggedIn } from '~/lib/utils/common_utils';
|
||||
import ForksButton from '~/forks/components/forks_button.vue';
|
||||
import MoreActionsDropdown from '~/groups_projects/components/more_actions_dropdown.vue';
|
||||
import NotificationsDropdown from '~/notifications/components/notifications_dropdown.vue';
|
||||
import StarCount from '~/stars/components/star_count.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ForksButton,
|
||||
MoreActionsDropdown,
|
||||
NotificationsDropdown,
|
||||
StarCount,
|
||||
},
|
||||
inject: {
|
||||
canReadProject: {
|
||||
default: false,
|
||||
},
|
||||
isProjectEmpty: {
|
||||
default: false,
|
||||
},
|
||||
projectId: {
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isLoggedIn: isLoggedIn(),
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
canForkProject() {
|
||||
return !this.isProjectEmpty && isLoggedIn() && this.canReadProject;
|
||||
},
|
||||
copyProjectId() {
|
||||
return sprintf(s__('ProjectPage|Project ID: %{id}'), { id: this.projectId });
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="gl-display-flex gl-gap-3">
|
||||
<template v-if="isLoggedIn && canReadProject">
|
||||
<notifications-dropdown />
|
||||
</template>
|
||||
|
||||
<star-count />
|
||||
|
||||
<forks-button v-if="canForkProject" />
|
||||
|
||||
<template v-if="canReadProject">
|
||||
<span class="gl-sr-only" itemprop="identifier" data-testid="project-id-content">
|
||||
{{ copyProjectId }}
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<more-actions-dropdown />
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
import { GlToast } from '@gitlab/ui';
|
||||
import Vue from 'vue';
|
||||
import VueApollo from 'vue-apollo';
|
||||
import createDefaultClient from '~/lib/graphql';
|
||||
|
||||
import { parseBoolean } from '~/lib/utils/common_utils';
|
||||
import HomePanel from './components/home_panel.vue';
|
||||
|
||||
Vue.use(GlToast);
|
||||
Vue.use(VueApollo);
|
||||
|
||||
const apolloProvider = new VueApollo({
|
||||
defaultClient: createDefaultClient(),
|
||||
});
|
||||
|
||||
const initHomePanel = () => {
|
||||
const container = document.getElementById('js-home-panel');
|
||||
|
||||
if (container === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const {
|
||||
// HomePanel component
|
||||
canReadProject,
|
||||
isProjectEmpty,
|
||||
projectId,
|
||||
|
||||
// Dropdown component
|
||||
isGroup,
|
||||
leaveConfirmMessage,
|
||||
leavePath,
|
||||
requestAccessPath,
|
||||
withdrawConfirmMessage,
|
||||
withdrawPath,
|
||||
|
||||
// Fork component
|
||||
canCreateFork,
|
||||
canForkProject,
|
||||
canReadCode,
|
||||
forksCount,
|
||||
newForkUrl,
|
||||
projectForksUrl,
|
||||
projectFullPath,
|
||||
userForkUrl,
|
||||
|
||||
// Notification component
|
||||
emailsDisabled,
|
||||
notificationDropdownItems,
|
||||
notificationHelpPagePath,
|
||||
notificationLevel,
|
||||
|
||||
// Star component
|
||||
signInPath,
|
||||
starCount,
|
||||
starred,
|
||||
starrersPath,
|
||||
} = container.dataset;
|
||||
|
||||
return new Vue({
|
||||
apolloProvider,
|
||||
el: container,
|
||||
name: 'HomePanelRoot',
|
||||
provide: {
|
||||
// HomePanel component
|
||||
canReadProject: parseBoolean(canReadProject),
|
||||
isProjectEmpty: parseBoolean(isProjectEmpty),
|
||||
projectId,
|
||||
|
||||
// Dropdown component
|
||||
groupOrProjectId: projectId,
|
||||
isGroup: parseBoolean(isGroup),
|
||||
leaveConfirmMessage,
|
||||
leavePath,
|
||||
requestAccessPath,
|
||||
withdrawConfirmMessage,
|
||||
withdrawPath,
|
||||
|
||||
// Fork component
|
||||
canCreateFork: parseBoolean(canCreateFork),
|
||||
canForkProject: parseBoolean(canForkProject),
|
||||
canReadCode: parseBoolean(canReadCode),
|
||||
forksCount: parseInt(forksCount, 10) || 0,
|
||||
newForkUrl,
|
||||
projectForksUrl,
|
||||
projectFullPath,
|
||||
userForkUrl,
|
||||
|
||||
// Notification component
|
||||
dropdownItems: JSON.parse(notificationDropdownItems || null),
|
||||
emailsDisabled: parseBoolean(emailsDisabled),
|
||||
helpPagePath: notificationHelpPagePath,
|
||||
initialNotificationLevel: notificationLevel,
|
||||
noFlip: true,
|
||||
|
||||
// Star component
|
||||
signInPath,
|
||||
starCount: parseInt(starCount, 10) || 0,
|
||||
starred: parseBoolean(starred),
|
||||
starrersPath,
|
||||
},
|
||||
render: (createElement) => createElement(HomePanel),
|
||||
});
|
||||
};
|
||||
|
||||
export { initHomePanel };
|
||||
|
|
@ -3,15 +3,12 @@ import { addShortcutsExtension } from '~/behaviors/shortcuts';
|
|||
import ShortcutsNavigation from '~/behaviors/shortcuts/shortcuts_navigation';
|
||||
import initClustersDeprecationAlert from '~/projects/clusters_deprecation_alert';
|
||||
import leaveByUrl from '~/namespaces/leave_by_url';
|
||||
import initVueNotificationsDropdown from '~/notifications';
|
||||
import initVueStarCount from '~/stars';
|
||||
import initTerraformNotification from '~/projects/terraform_notification';
|
||||
import { initUploadFileTrigger } from '~/projects/upload_file';
|
||||
import initReadMore from '~/read_more';
|
||||
import initForksButton from '~/forks/init_forks_button';
|
||||
import initAmbiguousRefModal from '~/ref/init_ambiguous_ref_modal';
|
||||
import InitMoreActionsDropdown from '~/groups_projects/init_more_actions_dropdown';
|
||||
import CodeDropdown from '~/vue_shared/components/code_dropdown/code_dropdown.vue';
|
||||
import { initHomePanel } from '../home_panel';
|
||||
|
||||
// Project show page loads different overview content based on user preferences
|
||||
if (document.getElementById('js-tree-list')) {
|
||||
|
|
@ -38,17 +35,14 @@ if (document.querySelector('.project-show-activity')) {
|
|||
.catch(() => {});
|
||||
}
|
||||
|
||||
initVueNotificationsDropdown();
|
||||
initVueStarCount();
|
||||
|
||||
addShortcutsExtension(ShortcutsNavigation);
|
||||
|
||||
initUploadFileTrigger();
|
||||
initClustersDeprecationAlert();
|
||||
initTerraformNotification();
|
||||
|
||||
initReadMore();
|
||||
initAmbiguousRefModal();
|
||||
initHomePanel();
|
||||
|
||||
if (document.querySelector('.js-autodevops-banner')) {
|
||||
import(/* webpackChunkName: 'userCallOut' */ '~/user_callout')
|
||||
|
|
@ -62,8 +56,6 @@ if (document.querySelector('.js-autodevops-banner')) {
|
|||
.catch(() => {});
|
||||
}
|
||||
|
||||
initForksButton();
|
||||
InitMoreActionsDropdown();
|
||||
leaveByUrl('project');
|
||||
|
||||
const initCodeDropdown = () => {
|
||||
|
|
|
|||
|
|
@ -31,14 +31,13 @@ const fetchData = (projectPath, path, ref, offset, refType) => {
|
|||
|
||||
fetchedBatches.push(offset);
|
||||
|
||||
const encodePathFunc = gon.features.encodingLogsTree ? encodeURI : encodeURIComponent;
|
||||
const url = joinPaths(
|
||||
gon.relative_url_root || '/',
|
||||
projectPath,
|
||||
'/-/refs/',
|
||||
encodePathFunc(ref),
|
||||
encodeURI(ref),
|
||||
'/logs_tree/',
|
||||
encodePathFunc(removeLeadingSlash(path)),
|
||||
encodeURI(removeLeadingSlash(path)),
|
||||
);
|
||||
|
||||
return axios
|
||||
|
|
|
|||
|
|
@ -1,40 +0,0 @@
|
|||
import { GlToast } from '@gitlab/ui';
|
||||
import Vue from 'vue';
|
||||
import VueApollo from 'vue-apollo';
|
||||
import createDefaultClient from '~/lib/graphql';
|
||||
import { parseBoolean } from '../lib/utils/common_utils';
|
||||
import StarCount from './components/star_count.vue';
|
||||
|
||||
Vue.use(GlToast);
|
||||
Vue.use(VueApollo);
|
||||
|
||||
const apolloProvider = new VueApollo({
|
||||
defaultClient: createDefaultClient(),
|
||||
});
|
||||
|
||||
export default () => {
|
||||
const containers = document.querySelectorAll('.js-vue-star-count');
|
||||
|
||||
if (containers.length === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return containers.forEach((el) => {
|
||||
const { projectId, starCount, starred, starrersPath, signInPath } = el.dataset;
|
||||
|
||||
return new Vue({
|
||||
el,
|
||||
provide: {
|
||||
starred: parseBoolean(starred),
|
||||
starCount,
|
||||
projectId,
|
||||
starrersPath,
|
||||
signInPath,
|
||||
},
|
||||
render(h) {
|
||||
return h(StarCount);
|
||||
},
|
||||
apolloProvider,
|
||||
});
|
||||
});
|
||||
};
|
||||
|
|
@ -30,7 +30,7 @@ export default {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<gl-link :href="helpLinks[storageType]" target="_blank" :aria-label="ariaLabel">
|
||||
<gl-icon name="question-o" :size="12" />
|
||||
<gl-link :href="helpLinks[storageType]" target="_blank" :aria-label="ariaLabel" class="gl-ml-3">
|
||||
<gl-icon name="question-o" :size="16" />
|
||||
</gl-link>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -75,8 +75,7 @@ export default {
|
|||
try {
|
||||
const response = await this.$apollo.query({
|
||||
query: getCurrentUserOrganizationsQuery,
|
||||
// TODO: implement search support - https://gitlab.com/gitlab-org/gitlab/-/issues/433954.
|
||||
variables: { after: this.endCursor, first: DEFAULT_PER_PAGE },
|
||||
variables: { search, after: this.endCursor, first: DEFAULT_PER_PAGE },
|
||||
});
|
||||
const { nodes, pageInfo } = response.data.currentUser.organizations;
|
||||
this.endCursor = pageInfo.endCursor;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
export const tdClass =
|
||||
'table-col gl-display-flex d-md-table-cell gl-align-items-center gl-white-space-nowrap';
|
||||
export const thClass = 'gl-hover-bg-blue-50';
|
||||
export const bodyTrClass =
|
||||
'gl-border-1 gl-border-t-solid gl-border-gray-100 gl-hover-cursor-pointer gl-hover-bg-gray-50 gl-hover-border-b-solid';
|
||||
|
||||
|
|
|
|||
|
|
@ -99,7 +99,9 @@ export default {
|
|||
return participantsQueries[this.issuableType].query;
|
||||
},
|
||||
skip() {
|
||||
return Boolean(participantsQueries[this.issuableType].skipQuery) || !this.isEditing;
|
||||
return (
|
||||
Boolean(participantsQueries[this.issuableType].skipQuery) || !this.isEditing || !this.iid
|
||||
);
|
||||
},
|
||||
variables() {
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -55,26 +55,3 @@ $tooltip-padding-y: 0.5rem;
|
|||
$tooltip-padding-x: 0.75rem;
|
||||
$tooltip-arrow-height: 0.5rem;
|
||||
$tooltip-arrow-width: 1rem;
|
||||
$b-table-sort-icon-bg-descending: url('data:image/svg+xml, <svg \
|
||||
xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="4 0 8 16"> \
|
||||
<path style="fill: #666;" fill-rule="evenodd" d="M11.707085,11.7071 \
|
||||
L7.999975,15.4142 L4.292875,11.7071 C3.902375,11.3166 3.902375, \
|
||||
10.6834 4.292875,10.2929 C4.683375,9.90237 \
|
||||
5.316575,9.90237 5.707075,10.2929 L6.999975, \
|
||||
11.5858 L6.999975,2 C6.999975,1.44771 \
|
||||
7.447695,1 7.999975,1 C8.552255,1 8.999975,1.44771 \
|
||||
8.999975,2 L8.999975,11.5858 L10.292865,10.2929 C10.683395 \
|
||||
,9.90237 11.316555,9.90237 11.707085,10.2929 \
|
||||
C12.097605,10.6834 12.097605,11.3166 11.707085,11.7071 Z"/> \
|
||||
</svg>') !default;
|
||||
$b-table-sort-icon-bg-ascending: url('data:image/svg+xml,<svg \
|
||||
xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="4 0 8 16"> \
|
||||
<path style="fill: #666;" fill-rule="evenodd" d="M4.29289,4.2971 L8,0.59 \
|
||||
L11.7071,4.2971 C12.0976,4.6876 \
|
||||
12.0976,5.3208 11.7071,5.7113 C11.3166,6.10183 10.6834, \
|
||||
6.10183 10.2929,5.7113 L9,4.4184 L9,14.0042 C9,14.55649 \
|
||||
8.55228,15.0042 8,15.0042 C7.44772,15.0042 7,14.55649 \
|
||||
7,14.0042 L7,4.4184 L5.70711,5.7113 C5.31658,6.10183 4.68342,6.10183 4.29289,5.7113 \
|
||||
C3.90237,5.3208 3.90237,4.6876 4.29289,4.2971 Z"/> \
|
||||
</svg> ') !default;
|
||||
$b-table-sort-icon-bg-not-sorted: '';
|
||||
|
|
|
|||
|
|
@ -46,7 +46,6 @@ class Projects::BlobController < Projects::ApplicationController
|
|||
|
||||
before_action do
|
||||
push_frontend_feature_flag(:explain_code_chat, current_user)
|
||||
push_frontend_feature_flag(:encoding_logs_tree)
|
||||
push_licensed_feature(:file_locks) if @project.licensed_feature_available?(:file_locks)
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ class Projects::TreeController < Projects::ApplicationController
|
|||
|
||||
before_action do
|
||||
push_frontend_feature_flag(:explain_code_chat, current_user)
|
||||
push_frontend_feature_flag(:encoding_logs_tree)
|
||||
push_licensed_feature(:file_locks) if @project.licensed_feature_available?(:file_locks)
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,6 @@ class ProjectsController < Projects::ApplicationController
|
|||
push_frontend_feature_flag(:remove_monitor_metrics, @project)
|
||||
push_frontend_feature_flag(:explain_code_chat, current_user)
|
||||
push_frontend_feature_flag(:issue_email_participants, @project)
|
||||
push_frontend_feature_flag(:encoding_logs_tree)
|
||||
push_frontend_feature_flag(:add_branch_rule, @project)
|
||||
# TODO: We need to remove the FF eventually when we rollout page_specific_styles
|
||||
push_frontend_feature_flag(:page_specific_styles, current_user)
|
||||
|
|
@ -196,7 +195,6 @@ class ProjectsController < Projects::ApplicationController
|
|||
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
@notification_setting = current_user.notification_settings_for(@project) if current_user
|
||||
@project = @project.present(current_user: current_user)
|
||||
render_landing_page
|
||||
end
|
||||
|
|
|
|||
|
|
@ -427,20 +427,21 @@ module ProjectsHelper
|
|||
|
||||
def fork_button_data_attributes(project)
|
||||
return unless current_user
|
||||
return if project.empty_repo?
|
||||
|
||||
if current_user.already_forked?(project) && current_user.forkable_namespaces.size < 2
|
||||
user_fork_url = namespace_project_path(current_user, current_user.fork_of(project))
|
||||
end
|
||||
|
||||
{
|
||||
forks_count: project.forks_count,
|
||||
project_full_path: project.full_path,
|
||||
project_forks_url: project_forks_path(project),
|
||||
user_fork_url: user_fork_url,
|
||||
new_fork_url: new_project_fork_path(project),
|
||||
can_read_code: can?(current_user, :read_code, project).to_s,
|
||||
can_create_fork: can?(current_user, :create_fork).to_s,
|
||||
can_fork_project: can?(current_user, :fork_project, project).to_s,
|
||||
can_create_fork: can?(current_user, :create_fork).to_s
|
||||
can_read_code: can?(current_user, :read_code, project).to_s,
|
||||
forks_count: project.forks_count,
|
||||
new_fork_url: new_project_fork_path(project),
|
||||
project_forks_url: project_forks_path(project),
|
||||
project_full_path: project.full_path,
|
||||
user_fork_url: user_fork_url
|
||||
}
|
||||
end
|
||||
|
||||
|
|
@ -448,16 +449,48 @@ module ProjectsHelper
|
|||
starred = current_user ? current_user.starred?(project) : false
|
||||
|
||||
{
|
||||
data: {
|
||||
project_id: project.id,
|
||||
sign_in_path: new_session_path(:user, redirect_to_referer: 'yes'),
|
||||
star_count: project.star_count,
|
||||
starred: starred.to_s,
|
||||
starrers_path: project_starrers_path(project)
|
||||
}
|
||||
project_id: project.id,
|
||||
sign_in_path: new_session_path(:user, redirect_to_referer: 'yes'),
|
||||
star_count: project.star_count,
|
||||
starred: starred.to_s,
|
||||
starrers_path: project_starrers_path(project)
|
||||
}
|
||||
end
|
||||
|
||||
def notification_data_attributes(project)
|
||||
return unless current_user
|
||||
|
||||
notification_setting = current_user.notification_settings_for(project)
|
||||
dropdown_items = notification_dropdown_items(notification_setting).to_json if notification_setting
|
||||
notification_level = notification_setting.level if notification_setting
|
||||
|
||||
{
|
||||
emails_disabled: project.emails_disabled?.to_s,
|
||||
notification_dropdown_items: dropdown_items,
|
||||
notification_help_page_path: help_page_path('user/profile/notifications'),
|
||||
notification_level: notification_level
|
||||
}
|
||||
end
|
||||
|
||||
def home_panel_data_attributes
|
||||
project = @project.is_a?(ProjectPresenter) ? @project.project : @project
|
||||
dropdown_attributes = groups_projects_more_actions_dropdown_data(project) || {}
|
||||
fork_button_attributes = fork_button_data_attributes(project) || {}
|
||||
notification_attributes = notification_data_attributes(project) || {}
|
||||
star_count_attributes = star_count_data_attributes(project)
|
||||
|
||||
{
|
||||
can_read_project: can?(current_user, :read_project, project).to_s,
|
||||
is_project_empty: project.empty_repo?.to_s,
|
||||
project_id: project.id
|
||||
}.merge(
|
||||
dropdown_attributes,
|
||||
fork_button_attributes,
|
||||
notification_attributes,
|
||||
star_count_attributes
|
||||
)
|
||||
end
|
||||
|
||||
def import_from_bitbucket_message
|
||||
configure_oauth_import_message('Bitbucket', help_page_path("integration/bitbucket"))
|
||||
end
|
||||
|
|
|
|||
|
|
@ -189,6 +189,10 @@ class BulkImports::Entity < ApplicationRecord
|
|||
project? ? project&.full_path : group&.full_path
|
||||
end
|
||||
|
||||
def full_path_with_fallback
|
||||
full_path || Gitlab::Utils.append_path(destination_namespace, destination_slug)
|
||||
end
|
||||
|
||||
def default_visibility_level
|
||||
return default_group_visibility if group?
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
- illustration_path = 'illustrations/empty-state/empty-activity-md.svg'
|
||||
- current_user_empty_message_header = s_('UserProfile|Join or create a group to start contributing by commenting on issues or submitting merge requests!')
|
||||
- current_user_empty_message_header = s_('UserProfile|No activities found')
|
||||
- current_user_empty_message_description = s_('UserProfile|Join or create a group to start contributing by commenting on issues or submitting merge requests!')
|
||||
- primary_button_label = _('New group')
|
||||
- primary_button_link = new_group_path
|
||||
- secondary_button_label = _('Explore groups')
|
||||
|
|
@ -11,6 +12,7 @@
|
|||
- else
|
||||
= render partial: 'shared/empty_states/profile_tabs', locals: { illustration_path: illustration_path,
|
||||
current_user_empty_message_header: current_user_empty_message_header,
|
||||
current_user_empty_message_description: current_user_empty_message_description,
|
||||
primary_button_label: primary_button_label,
|
||||
primary_button_link: primary_button_link,
|
||||
secondary_button_label: secondary_button_label,
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
= render Pajamas::ButtonComponent.new(href: new_project_path(namespace_id: @group.id), variant: :confirm, button_options: { data: { testid: 'new-project-button' }, class: 'gl-sm-w-auto gl-w-full' }) do
|
||||
= _('New project')
|
||||
|
||||
= render 'shared/groups_projects_more_actions_dropdown', source: @group
|
||||
= render 'groups/more_actions_dropdown', source: @group
|
||||
|
||||
- if @group.description.present?
|
||||
.group-home-desc.mt-1
|
||||
|
|
|
|||
|
|
@ -6,11 +6,5 @@
|
|||
%span.gl-sr-only{ itemprop: 'identifier', data: { testid: 'group-id-content' } }
|
||||
= s_('GroupPage|Group ID: %{id}') % { id: id }
|
||||
|
||||
- elsif can?(current_user, :read_project, @project)
|
||||
- id = @project.id
|
||||
|
||||
%span.gl-sr-only{ itemprop: 'identifier', data: { testid: 'project-id-content' } }
|
||||
= s_('ProjectPage|Project ID: %{id}') % { id: id }
|
||||
|
||||
- if id || current_user
|
||||
.js-groups-projects-more-actions-dropdown{ data: dropdown_data }
|
||||
|
|
@ -1,8 +1,7 @@
|
|||
- add_to_breadcrumbs _('New group'), new_group_path
|
||||
- add_to_breadcrumbs _('Import group'), new_group_path(anchor: 'import-group-pane')
|
||||
- add_to_breadcrumbs s_('BulkImport|Direct transfer history'), history_import_bulk_imports_path
|
||||
- if params[:id].present?
|
||||
- add_to_breadcrumbs params[:id], history_import_bulk_import_path(id: params[:id])
|
||||
- page_title format(s_('Import|Failures for %{id}'), id: params[:entity_id])
|
||||
- add_to_breadcrumbs @bulk_import.id, history_import_bulk_import_path(@bulk_import.id)
|
||||
- page_title format(s_('Import|Failures for %{id}'), id: @bulk_import_entity.full_path_with_fallback)
|
||||
|
||||
.js-bulk-import-details{ data: { id: params[:id], entity_id: params[:entity_id] } }
|
||||
.js-bulk-import-details{ data: { id: @bulk_import.id, entity_id: @bulk_import_entity.id, full_path: @bulk_import_entity.full_path_with_fallback } }
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
- empty_repo = @project.empty_repo?
|
||||
- emails_disabled = @project.emails_disabled?
|
||||
- ff_reorg_disabled = Feature.disabled?(:project_overview_reorg)
|
||||
|
||||
%header.project-home-panel.js-show-on-project-root.gl-mt-5{ class: [("empty-project" if empty_repo)] }
|
||||
|
|
@ -19,12 +18,8 @@
|
|||
- if current_user
|
||||
- if current_user.admin?
|
||||
= link_button_to nil, [:admin, @project], icon: 'admin', title: _('View project in admin area'), data: {toggle: 'tooltip', placement: 'top', container: 'body'}
|
||||
- if @notification_setting
|
||||
.js-vue-notification-dropdown{ data: { disabled: emails_disabled.to_s, dropdown_items: notification_dropdown_items(@notification_setting).to_json, notification_level: @notification_setting.level, help_page_path: help_page_path('user/profile/notifications'), project_id: @project.id, no_flip: 'true' } }
|
||||
|
||||
= render 'projects/buttons/star', project: @project
|
||||
= render 'projects/buttons/fork'
|
||||
= render 'shared/groups_projects_more_actions_dropdown', source: @project
|
||||
#js-home-panel{ data: home_panel_data_attributes }
|
||||
|
||||
- if ff_reorg_disabled
|
||||
- if can?(current_user, :read_code, @project)
|
||||
|
|
|
|||
|
|
@ -1,3 +0,0 @@
|
|||
- unless @project.empty_repo?
|
||||
- if current_user
|
||||
#js-forks-button{ data: fork_button_data_attributes(@project) }
|
||||
|
|
@ -1 +0,0 @@
|
|||
.js-vue-star-count{ star_count_data_attributes(@project) }
|
||||
|
|
@ -1,21 +1,23 @@
|
|||
- current_user_empty_message_description = local_assigns.fetch(:current_user_empty_message_description, nil)
|
||||
- secondary_button_link = local_assigns.fetch(:secondary_button_link, nil)
|
||||
- secondary_button_label = local_assigns.fetch(:secondary_button_label, nil)
|
||||
- primary_button_link = local_assigns.fetch(:primary_button_link, nil)
|
||||
- primary_button_label = local_assigns.fetch(:primary_button_label, nil)
|
||||
|
||||
- is_current_user = user_profile? && current_user.present? && current_user.username == params[:username]
|
||||
|
||||
.nothing-here-block
|
||||
.svg-content
|
||||
= image_tag illustration_path, size: '75'
|
||||
.text-content
|
||||
- if user_profile? && current_user.present? && current_user.username == params[:username]
|
||||
%h5= current_user_empty_message_header
|
||||
- if is_current_user
|
||||
= render Pajamas::EmptyStateComponent.new(svg_path: illustration_path,
|
||||
title: current_user_empty_message_header,
|
||||
primary_button_text: primary_button_label,
|
||||
primary_button_link: primary_button_link,
|
||||
secondary_button_text: secondary_button_label,
|
||||
secondary_button_link: secondary_button_link) do |c|
|
||||
|
||||
- c.with_description do
|
||||
- if current_user_empty_message_description.present?
|
||||
%p= current_user_empty_message_description
|
||||
|
||||
- if primary_button_link.present?
|
||||
= link_button_to primary_button_label, primary_button_link, variant: :confirm
|
||||
|
||||
- if secondary_button_link.present?
|
||||
= link_button_to secondary_button_label, secondary_button_link, variant: :confirm, category: :secondary
|
||||
- else
|
||||
%h5= visitor_empty_message
|
||||
= current_user_empty_message_description
|
||||
- else
|
||||
= render Pajamas::EmptyStateComponent.new(svg_path: illustration_path,
|
||||
title: visitor_empty_message)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
- illustration_path = 'illustrations/empty-state/empty-groups-md.svg'
|
||||
- current_user_empty_message_header = s_('UserProfile|You can create a group for several dependent projects.')
|
||||
- current_user_empty_message_header = s_('UserProfile|You can create a group for several dependent projects')
|
||||
- current_user_empty_message_description = s_('UserProfile|Groups are the best way to manage projects and members.')
|
||||
- primary_button_label = _('New group')
|
||||
- primary_button_link = new_group_path
|
||||
|
|
|
|||
|
|
@ -12,16 +12,16 @@
|
|||
- compact_mode = false unless local_assigns[:compact_mode] == true
|
||||
- card_mode = local_assigns[:card_mode] == true
|
||||
- css_classes = "#{'compact' if compact_mode} #{'explore' if explore_projects_tab?}"
|
||||
- contributed_projects_current_user_empty_message_header = s_('UserProfile|Explore public groups to find projects to contribute to.')
|
||||
- contributed_projects_current_user_empty_message_header = s_('UserProfile|Explore public groups to find projects to contribute to')
|
||||
- contributed_projects_visitor_empty_message = s_('UserProfile|This user hasn\'t contributed to any projects')
|
||||
- starred_projects_illustration_path = 'illustrations/empty-state/empty-projects-starred-md.svg'
|
||||
- starred_projects_current_user_empty_message_header = s_('UserProfile|Star projects to track their progress and show your appreciation.')
|
||||
- starred_projects_current_user_empty_message_header = s_('UserProfile|Star projects to track their progress and show your appreciation')
|
||||
- starred_projects_visitor_empty_message = s_('UserProfile|This user hasn\'t starred any projects')
|
||||
- own_projects_illustration_path = 'illustrations/empty-state/empty-projects-md.svg'
|
||||
- own_projects_current_user_empty_message_header = s_('UserProfile|You haven\'t created any personal projects.')
|
||||
- own_projects_current_user_empty_message_header = s_('UserProfile|You haven\'t created any personal projects')
|
||||
- own_projects_current_user_empty_message_description = s_('UserProfile|Your projects can be available publicly, internally, or privately, at your choice.')
|
||||
- own_projects_visitor_empty_message = s_('UserProfile|There are no projects available to be displayed here.')
|
||||
- explore_page_empty_message = s_('UserProfile|Explore public groups to find projects to contribute to.')
|
||||
- own_projects_visitor_empty_message = s_('UserProfile|There are no projects available to be displayed here')
|
||||
- explore_page_empty_message = s_('UserProfile|Explore public groups to find projects to contribute to')
|
||||
- new_project_button_label = _('New project')
|
||||
- new_project_button_link = new_project_path
|
||||
- explore_projects_button_label = _('Explore projects')
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
- followers_illustration_path = 'illustrations/empty-state/empty-friends-md.svg'
|
||||
- followers_visitor_empty_message = s_('UserProfile|This user doesn\'t have any followers.')
|
||||
- followers_current_user_empty_message_header = s_('UserProfile|You do not have any followers.')
|
||||
- followers_visitor_empty_message = s_('UserProfile|This user doesn\'t have any followers')
|
||||
- followers_current_user_empty_message_header = s_('UserProfile|You do not have any followers')
|
||||
- following_illustration_path = 'illustrations/empty-state/empty-friends-md.svg'
|
||||
- following_visitor_empty_message = s_('UserProfile|This user isn\'t following other users.')
|
||||
- following_current_user_empty_message_header = s_('UserProfile|You are not following other users.')
|
||||
- following_visitor_empty_message = s_('UserProfile|This user isn\'t following other users')
|
||||
- following_current_user_empty_message_header = s_('UserProfile|You are not following other users')
|
||||
|
||||
- if users.size > 0
|
||||
.row.gl-mt-3
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
- link_project = local_assigns.fetch(:link_project, false)
|
||||
- illustration_path = 'illustrations/empty-state/empty-snippets-md.svg'
|
||||
- current_user_empty_message_header = s_('UserProfile|You haven\'t created any snippets.')
|
||||
- current_user_empty_message_header = s_('UserProfile|You haven\'t created any snippets')
|
||||
- current_user_empty_message_description = s_('UserProfile|Snippets in GitLab can either be private, internal, or public.')
|
||||
- primary_button_label = _('New snippet')
|
||||
- primary_button_link = new_snippet_path if can?(current_user, :create_snippet)
|
||||
- visitor_empty_message = s_('UserProfile|No snippets found.')
|
||||
- visitor_empty_message = s_('UserProfile|No snippets found')
|
||||
|
||||
.snippets-list-holder
|
||||
%ul.content-list
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
---
|
||||
name: encoding_logs_tree
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/136323
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/432559
|
||||
milestone: '16.7'
|
||||
type: development
|
||||
group: group::source code
|
||||
default_enabled: false
|
||||
|
|
@ -789,6 +789,8 @@
|
|||
- 1
|
||||
- - work_items_update_parent_objectives_progress
|
||||
- 1
|
||||
- - work_items_validate_epic_work_item_sync
|
||||
- 1
|
||||
- - x509_certificate_revoke
|
||||
- 1
|
||||
- - zoekt_indexer
|
||||
|
|
|
|||
|
|
@ -16500,6 +16500,7 @@ Options for runner Google Cloud provisioning.
|
|||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="cirunnergooglecloudprovisioningoptionsprojectsetupshellscript"></a>`projectSetupShellScript` | [`String`](#string) | Instructions for setting up a Google Cloud project. |
|
||||
| <a id="cirunnergooglecloudprovisioningoptionsregions"></a>`regions` | [`CiRunnerCloudProvisioningRegionConnection`](#cirunnercloudprovisioningregionconnection) | Regions available for provisioning a runner. (see [Connections](#connections)) |
|
||||
|
||||
#### Fields with arguments
|
||||
|
|
@ -26344,7 +26345,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
|
|||
|
||||
##### `Project.runnerCloudProvisioningOptions`
|
||||
|
||||
Options for provisioning the runner on Google Cloud. Returns `null` if `:google_cloud_runner_provisioning` feature flag is disabled, or the GitLab instance is not a SaaS instance.
|
||||
Options for provisioning the runner on a cloud provider. Returns `null` if `:google_cloud_runner_provisioning` feature flag is disabled, or the GitLab instance is not a SaaS instance.
|
||||
|
||||
NOTE:
|
||||
**Introduced** in 16.9.
|
||||
|
|
|
|||
|
|
@ -22,20 +22,22 @@ To update the documentation:
|
|||
|
||||
1. Go to the [GitLab community fork](https://gitlab.com/gitlab-community/gitlab) or your own fork.
|
||||
1. Find the documentation page in the `\doc` directory.
|
||||
1. If you know Git, make your changes and open a merge request.
|
||||
If not, follow these steps:
|
||||
1. In the upper right, select **Edit > Edit single file**.
|
||||
1. Make your changes.
|
||||
1. When you're ready to submit your changes, in the **Commit message** text box, enter a commit message.
|
||||
Use 3-5 words, start with a capital letter, and do not end with a period.
|
||||
1. Select **Commit changes**.
|
||||
1. In the upper right, select **Edit > Edit single file**.
|
||||
1. Make your changes.
|
||||
1. When you're ready to submit your changes, in the **Commit message** text box, enter a commit message.
|
||||
Use 3-5 words, start with a capital letter, and do not end with a period.
|
||||
1. Select **Commit changes**.
|
||||
1. If you're working from the community fork, a new merge request opens and you can continue to the next step.
|
||||
If you're working from your own fork, first do the following:
|
||||
1. On the left sidebar, select **Code > Merge requests**.
|
||||
1. Select **New merge request**.
|
||||
1. For the source branch, select your fork and branch. If you did not create a branch, select `master`.
|
||||
For the target branch, select the [GitLab repository](https://gitlab.com/gitlab-org/gitlab) `master` branch.
|
||||
1. Select **Compare branches and continue**. A new merge request opens.
|
||||
1. Select the **Documentation** template. In the description, write a brief summary of the changes and link to the related issue, if there is one.
|
||||
1. Select **Create merge request**.
|
||||
1. On the **New merge request** page, select the **Documentation** template and select **Apply template**.
|
||||
1. In the description, write a brief summary of the changes and link to the related issue, if there is one.
|
||||
1. Select **Create merge request**.
|
||||
1. After your merge request is created, look for a message from **GitLab Bot**. This message has instructions for what to do when you're ready for review.
|
||||
|
||||
Alternatively, if you don't want to search through the `/doc` directory, on <https://docs.gitlab.com>, at the bottom of any page, select **View page source** or **Edit in Web IDE**.
|
||||
You are prompted to create a fork or switch to your fork before you can make changes.
|
||||
|
|
|
|||
|
|
@ -82,6 +82,11 @@ planned for release in 16.9.1.
|
|||
directly to 16.8.2, which [restores compatibility with Redis 6.0](https://gitlab.com/gitlab-org/gitlab/-/issues/439418).
|
||||
- NOTE: You should upgrade to Redis 6.2 or later as [Redis 6.0 is no longer supported](https://endoflife.date/redis).
|
||||
|
||||
- Backups in environments that have PgBouncer must [bypass PgBouncer by setting variables that are prefixed with `GITLAB_BACKUP_`](../../administration/backup_restore/backup_gitlab.md#bypassing-pgbouncer). But due to an [issue](https://gitlab.com/gitlab-org/gitlab/-/issues/422163), `gitlab-backup` uses the regular database connection through PgBouncer instead of the direct connection defined in the override, and the database backup fails. The workaround is to use `pg_dump` directly.
|
||||
|
||||
- Affected releases: 15.11.x - 16.8.x
|
||||
- Fixed in: 16.9
|
||||
|
||||
### Geo installations
|
||||
|
||||
- PostgreSQL version 14 is the default for fresh installations of GitLab 16.7 and later. Due to a known issue, existing Geo secondary
|
||||
|
|
|
|||
|
|
@ -308,7 +308,7 @@ in the hierarchy.
|
|||
|
||||
To ensure that the user cap applies when groups, subgroups, or projects are shared externally, restrict group sharing only within the top-level namespace. This ensure that groups in the same top-leve namespace can be invited, and prevents the addition of new users (seats) when the group is shared.
|
||||
|
||||
User cap doesn’t consider whether users are billable or not (e.g., Free Guest Users in Ultimate). In other words, if you set a cap of 500, user caps block new sign-ups after 500 users, regardless of whether those are all consuming paid seats or not.
|
||||
On GitLab.com, on the Ultimate tier, there is a [known issue](https://gitlab.com/gitlab-org/gitlab/-/issues/441504) where you cannot add new guest users to a group when the amount of billable users exceeds the user cap. For example, suppose you have a user cap of 5, with 3 developers and 2 guests. After you add 2 more developers, you cannot add any more users, even if they are guest users that don't consume a billable seat.
|
||||
|
||||
## Group file templates
|
||||
|
||||
|
|
|
|||
|
|
@ -200,8 +200,6 @@ DETAILS:
|
|||
**Tier:** Premium, Ultimate
|
||||
**Offering:** SaaS, self-managed
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/440) in GitLab 8.9.
|
||||
|
||||
This process allows you to lock one file at a time through the GitLab UI and
|
||||
requires access to the [GitLab Premium or Ultimate tier](https://about.gitlab.com/pricing/).
|
||||
|
||||
|
|
|
|||
|
|
@ -10,8 +10,6 @@ DETAILS:
|
|||
**Tier:** Free, Premium, Ultimate
|
||||
**Offering:** SaaS, self-managed
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/3619) in GitLab 13.6.
|
||||
|
||||
Export all the data collected from a project's merge requests into a comma-separated values (CSV) file.
|
||||
|
||||
To export merge requests to a CSV file:
|
||||
|
|
|
|||
|
|
@ -55,15 +55,23 @@ For more information, see [Data usage in GitLab Duo Suggested Reviewers](data_us
|
|||
|
||||
### Enable Suggested Reviewers
|
||||
|
||||
Project Maintainers or Owners can enable Suggested Reviewers by visiting
|
||||
the [project settings](../../settings/index.md).
|
||||
|
||||
Enabling Suggested Reviewers triggers GitLab to create an ML model for your
|
||||
project that is used to generate reviewers. The larger your project, the longer
|
||||
this process can take. Usually, the model is ready to generate suggestions
|
||||
within a few hours.
|
||||
|
||||
No action is required after the feature is enabled. After the model is ready,
|
||||
Prerequisites:
|
||||
|
||||
- You have the Owner or Maintainer role in the project.
|
||||
|
||||
To do this:
|
||||
|
||||
1. On the left sidebar, select **Search or go to** and find your project.
|
||||
1. Select **Settings > Merge requests**.
|
||||
1. Scroll to **Suggested reviewers**, and select **Enable suggested reviewers**.
|
||||
1. Select **Save changes**.
|
||||
|
||||
After you enable the feature, no additional action is needed. After the model is ready,
|
||||
recommendations populate the **Reviewer** dropdown list in the right-hand sidebar
|
||||
of a merge request with new commits.
|
||||
|
||||
|
|
@ -112,8 +120,6 @@ DETAILS:
|
|||
**Tier:** Premium, Ultimate
|
||||
**Offering:** SaaS, self-managed
|
||||
|
||||
> - Moved to GitLab Premium in 13.9.
|
||||
|
||||
To assign multiple reviewers to a merge request, in a text area in
|
||||
the merge request, use the `/assign_reviewer @user`
|
||||
[quick action](../../quick_actions.md#issues-merge-requests-and-epics). Alternatively:
|
||||
|
|
|
|||
|
|
@ -46,7 +46,9 @@ Prerequisites:
|
|||
|
||||
To do this:
|
||||
|
||||
1. Go to the merge request and select **Edit**.
|
||||
1. On the left sidebar, select **Search or go to** and find your project.
|
||||
1. Select **Code > Merge requests** and find your merge request.
|
||||
1. Select **Edit**.
|
||||
1. Select or clear the **Squash commits when merge request is accepted** checkbox.
|
||||
1. Select **Save changes**.
|
||||
|
||||
|
|
@ -55,8 +57,9 @@ To do this:
|
|||
If your project allows you to select squashing options for merge requests, to
|
||||
squash the commits as part of the merge process:
|
||||
|
||||
1. Go to the merge request, and scroll to the merge request reports section that
|
||||
contains the **Merge** button.
|
||||
1. On the left sidebar, select **Search or go to** and find your project.
|
||||
1. Select **Code > Merge requests** and find your merge request.
|
||||
1. Scroll to the merge request reports section that contains the **Merge** button.
|
||||
1. Ensure the **Squash commits** checkbox is selected. This checkbox doesn't display
|
||||
if the project's squashing option is set to either **Do not allow** or **Require**.
|
||||
1. Optional. To modify either the squash commit message or the merge commit message
|
||||
|
|
@ -65,10 +68,6 @@ squash the commits as part of the merge process:
|
|||
|
||||
## Configure squash options for a project
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/17613) in GitLab 13.2 [with a flag](../../../administration/feature_flags.md) named `squash_options`, disabled by default.
|
||||
> - [Enabled on GitLab.com and self-managed by default](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/39382) in GitLab 13.3.
|
||||
> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/232536) in GitLab 13.8. Feature flag `squash_options` removed.
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- You must have at least the Maintainer role for this project.
|
||||
|
|
|
|||
|
|
@ -80,7 +80,8 @@ using the API. You don't need to wait for a merge request webhook payload to be
|
|||
|
||||
Within each project's settings, you can see a list of status check services added to the project:
|
||||
|
||||
1. In your project, go to **Settings > Merge requests** section.
|
||||
1. On the left sidebar, select **Search or go to** and find your project.
|
||||
1. Select **Settings > Merge requests**.
|
||||
1. Scroll down to **Status checks**.
|
||||
|
||||

|
||||
|
|
@ -121,8 +122,8 @@ The name **has** to be unique for the project.
|
|||
|
||||
#### API to check
|
||||
|
||||
This field requires a URL and **must** use either the HTTP or HTTPs protocols.
|
||||
We **recommend** using HTTPs to protect your merge request data in transit.
|
||||
This field requires a URL and **must** use either the HTTP or HTTPS protocols.
|
||||
We **recommend** using HTTPS to protect your merge request data in transit.
|
||||
The URL **must** be set and **must** be unique for the project.
|
||||
|
||||
#### Target branch
|
||||
|
|
@ -170,7 +171,9 @@ When there are pending status checks, the widget polls for updates every few sec
|
|||
|
||||
To retry a failed status check:
|
||||
|
||||
1. Expand the merge request widget to show the list of external status checks.
|
||||
1. On the left sidebar, select **Search or go to** and find your project.
|
||||
1. Select **Code > Merge requests** and find your merge request.
|
||||
1. Scroll to the merge request reports section, and expand the dropdown list to show the list of external status checks.
|
||||
1. Select **Retry** (**{retry}**) on the failed external status check row. The status check is put back into a pending state.
|
||||
|
||||
An organization might have a policy that does not allow merging merge requests if
|
||||
|
|
|
|||
|
|
@ -78,7 +78,6 @@ module Gitlab
|
|||
push_frontend_feature_flag(:ui_for_organizations, current_user)
|
||||
# To be removed with https://gitlab.com/gitlab-org/gitlab/-/issues/399248
|
||||
push_frontend_feature_flag(:remove_monitor_metrics)
|
||||
push_frontend_feature_flag(:encoding_logs_tree)
|
||||
push_frontend_feature_flag(:group_user_saml)
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -5802,6 +5802,9 @@ msgstr ""
|
|||
msgid "Analytics|Visualization was saved successfully"
|
||||
msgstr ""
|
||||
|
||||
msgid "Analytics|Would you like to replace your existing selection with a new visualization generated through GitLab Duo?"
|
||||
msgstr ""
|
||||
|
||||
msgid "Analyze your dependencies for known vulnerabilities."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -13765,6 +13768,9 @@ msgstr ""
|
|||
msgid "Continue to the next step"
|
||||
msgstr ""
|
||||
|
||||
msgid "Continue with GitLab Duo"
|
||||
msgstr ""
|
||||
|
||||
msgid "Continue with overages"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -13864,9 +13870,15 @@ msgstr ""
|
|||
msgid "ContributionAnalytics|There is too much data to calculate. Try lowering the period_limit setting in the insights configuration file."
|
||||
msgstr ""
|
||||
|
||||
msgid "ContributionAnalytics|This page sources data from the %{link_start}analytical database ClickHouse%{link_end}, with a few minutes of delay."
|
||||
msgstr ""
|
||||
|
||||
msgid "ContributionAnalytics|Total Contributions"
|
||||
msgstr ""
|
||||
|
||||
msgid "ContributionAnalytics|Using ClickHouse"
|
||||
msgstr ""
|
||||
|
||||
msgid "ContributionEvent|Accepted merge request %{targetLink} in %{resourceParentLink}."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -35381,6 +35393,9 @@ msgstr ""
|
|||
msgid "PackageRegistry|Published to the %{project} Package Registry %{datetime}"
|
||||
msgstr ""
|
||||
|
||||
msgid "PackageRegistry|Published to the %{project} Terraform Module Registry %{datetime}"
|
||||
msgstr ""
|
||||
|
||||
msgid "PackageRegistry|Push protected up to access level"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -54257,7 +54272,7 @@ msgstr ""
|
|||
msgid "UserProfile|Edit profile"
|
||||
msgstr ""
|
||||
|
||||
msgid "UserProfile|Explore public groups to find projects to contribute to."
|
||||
msgid "UserProfile|Explore public groups to find projects to contribute to"
|
||||
msgstr ""
|
||||
|
||||
msgid "UserProfile|Failed to set avatar. Please reload the page to try again."
|
||||
|
|
@ -54284,7 +54299,10 @@ msgstr ""
|
|||
msgid "UserProfile|Join or create a group to start contributing by commenting on issues or submitting merge requests!"
|
||||
msgstr ""
|
||||
|
||||
msgid "UserProfile|No snippets found."
|
||||
msgid "UserProfile|No activities found"
|
||||
msgstr ""
|
||||
|
||||
msgid "UserProfile|No snippets found"
|
||||
msgstr ""
|
||||
|
||||
msgid "UserProfile|Overview"
|
||||
|
|
@ -54308,7 +54326,7 @@ msgstr ""
|
|||
msgid "UserProfile|Snippets in GitLab can either be private, internal, or public."
|
||||
msgstr ""
|
||||
|
||||
msgid "UserProfile|Star projects to track their progress and show your appreciation."
|
||||
msgid "UserProfile|Star projects to track their progress and show your appreciation"
|
||||
msgstr ""
|
||||
|
||||
msgid "UserProfile|Starred projects"
|
||||
|
|
@ -54320,15 +54338,12 @@ msgstr ""
|
|||
msgid "UserProfile|Subscribe"
|
||||
msgstr ""
|
||||
|
||||
msgid "UserProfile|There are no projects available to be displayed here."
|
||||
msgid "UserProfile|There are no projects available to be displayed here"
|
||||
msgstr ""
|
||||
|
||||
msgid "UserProfile|This user doesn't have any followers"
|
||||
msgstr ""
|
||||
|
||||
msgid "UserProfile|This user doesn't have any followers."
|
||||
msgstr ""
|
||||
|
||||
msgid "UserProfile|This user doesn't have any snippets"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -54347,9 +54362,6 @@ msgstr ""
|
|||
msgid "UserProfile|This user isn't following other users"
|
||||
msgstr ""
|
||||
|
||||
msgid "UserProfile|This user isn't following other users."
|
||||
msgstr ""
|
||||
|
||||
msgid "UserProfile|Unconfirmed user"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -54374,22 +54386,16 @@ msgstr ""
|
|||
msgid "UserProfile|You are not following other users"
|
||||
msgstr ""
|
||||
|
||||
msgid "UserProfile|You are not following other users."
|
||||
msgstr ""
|
||||
|
||||
msgid "UserProfile|You can create a group for several dependent projects."
|
||||
msgid "UserProfile|You can create a group for several dependent projects"
|
||||
msgstr ""
|
||||
|
||||
msgid "UserProfile|You do not have any followers"
|
||||
msgstr ""
|
||||
|
||||
msgid "UserProfile|You do not have any followers."
|
||||
msgid "UserProfile|You haven't created any personal projects"
|
||||
msgstr ""
|
||||
|
||||
msgid "UserProfile|You haven't created any personal projects."
|
||||
msgstr ""
|
||||
|
||||
msgid "UserProfile|You haven't created any snippets."
|
||||
msgid "UserProfile|You haven't created any snippets"
|
||||
msgstr ""
|
||||
|
||||
msgid "UserProfile|Your projects can be available publicly, internally, or privately, at your choice."
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@
|
|||
"@gitlab/favicon-overlay": "2.0.0",
|
||||
"@gitlab/fonts": "^1.3.0",
|
||||
"@gitlab/svgs": "3.84.0",
|
||||
"@gitlab/ui": "^74.9.1",
|
||||
"@gitlab/ui": "^74.9.3",
|
||||
"@gitlab/visual-review-tools": "1.7.3",
|
||||
"@gitlab/web-ide": "^0.0.1-dev-20240214084918",
|
||||
"@mattiasbuelens/web-streams-adapter": "^0.1.0",
|
||||
|
|
|
|||
|
|
@ -173,40 +173,11 @@ RSpec.describe ProjectsController, feature_category: :groups_and_projects do
|
|||
sign_in(user)
|
||||
end
|
||||
|
||||
context "user does not have access to project" do
|
||||
let(:private_project) { create(:project, :private) }
|
||||
|
||||
it "does not initialize notification setting" do
|
||||
get :show, params: { namespace_id: private_project.namespace, id: private_project }
|
||||
expect(assigns(:notification_setting)).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context "user has access to project" do
|
||||
before do
|
||||
expect(::Gitlab::GitalyClient).to receive(:allow_ref_name_caching).and_call_original
|
||||
end
|
||||
|
||||
context "and does not have notification setting" do
|
||||
it "initializes notification as disabled" do
|
||||
get :show, params: { namespace_id: public_project.namespace, id: public_project }
|
||||
expect(assigns(:notification_setting).level).to eq("global")
|
||||
end
|
||||
end
|
||||
|
||||
context "and has notification setting" do
|
||||
before do
|
||||
setting = user.notification_settings_for(public_project)
|
||||
setting.level = :watch
|
||||
setting.save!
|
||||
end
|
||||
|
||||
it "shows current notification setting" do
|
||||
get :show, params: { namespace_id: public_project.namespace, id: public_project }
|
||||
expect(assigns(:notification_setting).level).to eq("watch")
|
||||
end
|
||||
end
|
||||
|
||||
context 'when ambiguous_ref_modal is disabled' do
|
||||
before do
|
||||
stub_feature_flags(ambiguous_ref_modal: false)
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ RSpec.describe 'Dashboard shortcuts', :js, feature_category: :shared do
|
|||
find('body').send_keys([:shift, 'P'])
|
||||
|
||||
find('.nothing-here-block')
|
||||
expect(page).to have_content('Explore public groups to find projects to contribute to.')
|
||||
expect(page).to have_content('Explore public groups to find projects to contribute to')
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ RSpec.describe 'Dashboard > User filters projects', feature_category: :groups_an
|
|||
it 'returns message when starred projects fitler returns no results' do
|
||||
fill_in 'project-filter-form-field', with: 'Beta\n'
|
||||
|
||||
expect(page).to have_content('There are no projects available to be displayed here.')
|
||||
expect(page).to have_content('There are no projects available to be displayed here')
|
||||
expect(page).not_to have_content('You don\'t have starred projects yet')
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ RSpec.describe 'User explores projects', feature_category: :user_profile do
|
|||
it 'shows correct empty state message', :js do
|
||||
fill_in 'name', with: 'zzzzzzzzzzzzzzzzzzz'
|
||||
|
||||
expect(page).to have_content('Explore public groups to find projects to contribute to.')
|
||||
expect(page).to have_content('Explore public groups to find projects to contribute to')
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -133,7 +133,7 @@ RSpec.describe 'User explores projects', feature_category: :user_profile do
|
|||
context 'when there are no projects' do
|
||||
shared_examples 'explore page empty state' do
|
||||
it 'shows correct empty state message' do
|
||||
expect(page).to have_content('Explore public groups to find projects to contribute to.')
|
||||
expect(page).to have_content('Explore public groups to find projects to contribute to')
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ RSpec.describe 'Topic show page', feature_category: :groups_and_projects do
|
|||
|
||||
context 'without associated projects' do
|
||||
it 'shows correct empty state message' do
|
||||
expect(page).to have_content('Explore public groups to find projects to contribute to.')
|
||||
expect(page).to have_content('Explore public groups to find projects to contribute to')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ describe('~/access_tokens/components/access_token_table_app', () => {
|
|||
__('Token name'),
|
||||
__('Scopes'),
|
||||
s__('AccessTokens|Created'),
|
||||
__('Last Used'),
|
||||
'Last Used The last time a token was used',
|
||||
__('Expires'),
|
||||
__('Action'),
|
||||
]);
|
||||
|
|
@ -114,7 +114,7 @@ describe('~/access_tokens/components/access_token_table_app', () => {
|
|||
__('Token name'),
|
||||
__('Scopes'),
|
||||
s__('AccessTokens|Created'),
|
||||
__('Last Used'),
|
||||
'Last Used The last time a token was used',
|
||||
__('Expires'),
|
||||
__('Role'),
|
||||
__('Action'),
|
||||
|
|
@ -192,7 +192,7 @@ describe('~/access_tokens/components/access_token_table_app', () => {
|
|||
__('Token name'),
|
||||
__('Scopes'),
|
||||
s__('AccessTokens|Created'),
|
||||
__('Last Used'),
|
||||
'Last Used The last time a token was used',
|
||||
__('Expires'),
|
||||
__('Role'),
|
||||
].forEach((text, index) => {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { GlTable, GlAlert, GlLoadingIcon, GlDropdown, GlIcon, GlAvatar, GlLink } from '@gitlab/ui';
|
||||
import { GlTable, GlAlert, GlLoadingIcon, GlDropdown, GlAvatar, GlLink } from '@gitlab/ui';
|
||||
import { mount } from '@vue/test-utils';
|
||||
import axios from 'axios';
|
||||
import MockAdapter from 'axios-mock-adapter';
|
||||
|
|
@ -174,7 +174,7 @@ describe('AlertManagementTable', () => {
|
|||
await nextTick();
|
||||
|
||||
expect(wrapper.findComponent(GlTable).exists()).toBe(true);
|
||||
expect(findAlertsTable().findComponent(GlIcon).classes('icon-critical')).toBe(true);
|
||||
expect(findAlertsTable().find('[data-testid="severity-critical-icon"]').exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('renders severity text', () => {
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ describe('behaviors/markdown/render_json_table', () => {
|
|||
const TEST_LABELS = TEST_DATA.fields.map((x) => x.label);
|
||||
|
||||
const tableAsData = (table) => ({
|
||||
head: Array.from(table.querySelectorAll('thead th')).map((td) => td.textContent),
|
||||
head: Array.from(table.querySelectorAll('thead th')).map((td) => td.textContent.trim()),
|
||||
body: Array.from(table.querySelectorAll('tbody > tr')).map((tr) =>
|
||||
Array.from(tr.querySelectorAll('td')).map((x) => x.textContent),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ describe('Ci variable table', () => {
|
|||
wrapper.findAllByTestId('ci-variable-table-row-attributes').at(rowIndex);
|
||||
const findAttributeByIndex = (rowIndex, attributeIndex) =>
|
||||
findAttributesRow(rowIndex).findAllComponents(GlBadge).at(attributeIndex).text();
|
||||
const findTableColumnText = (index) => wrapper.findAll('th').at(index).text();
|
||||
const findTableColumnText = (index) => wrapper.findAll('th > div').at(index).text();
|
||||
const findVariableRow = (rowIndex) =>
|
||||
wrapper.findAllByTestId('ci-variable-table-row-variable').at(rowIndex);
|
||||
const findGroupCiCdSettingsLink = (rowIndex) =>
|
||||
|
|
@ -105,7 +105,7 @@ describe('Ci variable table', () => {
|
|||
// last column is for the edit button, which has no text
|
||||
it.each`
|
||||
index | text
|
||||
${0} | ${'Key (Click to sort descending)'}
|
||||
${0} | ${'Key'}
|
||||
${1} | ${'Value'}
|
||||
${2} | ${'Environments'}
|
||||
${3} | ${'Actions'}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ describe('moreActionsDropdown', () => {
|
|||
wrapper = shallowMountExtended(moreActionsDropdown, {
|
||||
provide: {
|
||||
isGroup: false,
|
||||
id: 1,
|
||||
groupOrProjectId: 1,
|
||||
leavePath: '',
|
||||
leaveConfirmMessage: '',
|
||||
withdrawPath: '',
|
||||
|
|
@ -39,7 +39,7 @@ describe('moreActionsDropdown', () => {
|
|||
beforeEach(async () => {
|
||||
createComponent({
|
||||
provideData: {
|
||||
id: 22,
|
||||
groupOrProjectId: 22,
|
||||
},
|
||||
});
|
||||
await showDropdown();
|
||||
|
|
@ -60,7 +60,7 @@ describe('moreActionsDropdown', () => {
|
|||
createComponent({
|
||||
provideData: {
|
||||
isGroup: true,
|
||||
id: 11,
|
||||
groupOrProjectId: 11,
|
||||
},
|
||||
});
|
||||
await showDropdown();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,65 @@
|
|||
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
|
||||
import HomePanel from '~/pages/projects/home_panel/components/home_panel.vue';
|
||||
import ForksButton from '~/forks/components/forks_button.vue';
|
||||
import MoreActionsDropdown from '~/groups_projects/components/more_actions_dropdown.vue';
|
||||
import NotificationsDropdown from '~/notifications/components/notifications_dropdown.vue';
|
||||
import StarCount from '~/stars/components/star_count.vue';
|
||||
|
||||
describe('HomePanel', () => {
|
||||
let wrapper;
|
||||
|
||||
const createComponent = ({ isLoggedIn = false, provide = {} } = {}) => {
|
||||
if (isLoggedIn) {
|
||||
window.gon.current_user_id = 1;
|
||||
}
|
||||
|
||||
wrapper = shallowMountExtended(HomePanel, {
|
||||
provide: {
|
||||
...provide,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const findForksButton = () => wrapper.findComponent(ForksButton);
|
||||
const findMoreActionsDropdown = () => wrapper.findComponent(MoreActionsDropdown);
|
||||
const findNotificationsDropdown = () => wrapper.findComponent(NotificationsDropdown);
|
||||
const findStarCount = () => wrapper.findComponent(StarCount);
|
||||
|
||||
describe.each`
|
||||
isLoggedIn | canReadProject | isProjectEmpty | isForkButtonVisible | isMoreActionsDropdownVisible | isNotificationDropdownVisible | isStarCountVisible
|
||||
${true} | ${true} | ${true} | ${false} | ${true} | ${true} | ${true}
|
||||
${true} | ${true} | ${false} | ${true} | ${true} | ${true} | ${true}
|
||||
${true} | ${false} | ${true} | ${false} | ${true} | ${false} | ${true}
|
||||
${true} | ${false} | ${false} | ${false} | ${true} | ${false} | ${true}
|
||||
${false} | ${true} | ${true} | ${false} | ${true} | ${false} | ${true}
|
||||
${false} | ${true} | ${false} | ${false} | ${true} | ${false} | ${true}
|
||||
${false} | ${false} | ${true} | ${false} | ${true} | ${false} | ${true}
|
||||
${false} | ${false} | ${false} | ${false} | ${true} | ${false} | ${true}
|
||||
`(
|
||||
'renders components',
|
||||
({
|
||||
isLoggedIn,
|
||||
canReadProject,
|
||||
isProjectEmpty,
|
||||
isForkButtonVisible,
|
||||
isMoreActionsDropdownVisible,
|
||||
isNotificationDropdownVisible,
|
||||
isStarCountVisible,
|
||||
}) => {
|
||||
it('as expected', () => {
|
||||
createComponent({
|
||||
isLoggedIn,
|
||||
provide: {
|
||||
canReadProject,
|
||||
isProjectEmpty,
|
||||
},
|
||||
});
|
||||
|
||||
expect(findForksButton().exists()).toBe(isForkButtonVisible);
|
||||
expect(findMoreActionsDropdown().exists()).toBe(isMoreActionsDropdownVisible);
|
||||
expect(findNotificationsDropdown().exists()).toBe(isNotificationDropdownVisible);
|
||||
expect(findStarCount().exists()).toBe(isStarCountVisible);
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
|
|
@ -15,9 +15,12 @@ describe('Bulk import details app', () => {
|
|||
entityId: mockEntityId,
|
||||
};
|
||||
|
||||
const createComponent = () => {
|
||||
const createComponent = ({ props = {} } = {}) => {
|
||||
wrapper = shallowMount(BulkImportDetailsApp, {
|
||||
propsData: { ...defaultProps },
|
||||
propsData: {
|
||||
...defaultProps,
|
||||
...props,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
|
|
@ -32,6 +35,20 @@ describe('Bulk import details app', () => {
|
|||
expect(headingText).toBe(`Items that failed to be imported for ${mockEntityId}`);
|
||||
});
|
||||
|
||||
it('renders heading with fullPath when provided', () => {
|
||||
const mockFullPath = 'full/path';
|
||||
|
||||
createComponent({
|
||||
props: {
|
||||
fullPath: mockFullPath,
|
||||
},
|
||||
});
|
||||
|
||||
const headingText = wrapper.find('h1').text();
|
||||
|
||||
expect(headingText).toBe(`Items that failed to be imported for ${mockFullPath}`);
|
||||
});
|
||||
|
||||
it('renders import table', () => {
|
||||
createComponent();
|
||||
|
||||
|
|
|
|||
|
|
@ -118,7 +118,9 @@ describe('MembersTable', () => {
|
|||
tableFields: [field],
|
||||
});
|
||||
|
||||
expect(wrapper.findByText(label, { selector: '[role="columnheader"]' }).exists()).toBe(true);
|
||||
expect(wrapper.findByText(label, { selector: '[role="columnheader"] > div' }).exists()).toBe(
|
||||
true,
|
||||
);
|
||||
|
||||
if (expectedComponent) {
|
||||
expect(
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ describe('Package History', () => {
|
|||
${'created-on'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'clock'} | ${'Test package version 1.0.0 was first created'} | ${mavenPackage.created_at} | ${null}
|
||||
${'first-pipeline-commit'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'commit'} | ${'Created by commit sha-baz on branch branch-name'} | ${null} | ${mockPipelineInfo.project.commit_url}
|
||||
${'first-pipeline-pipeline'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'pipeline'} | ${'Built by pipeline #1 triggered by foo'} | ${mockPipelineInfo.created_at} | ${mockPipelineInfo.project.pipeline_url}
|
||||
${'published'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'package'} | ${'Published to the baz project Package Registry'} | ${mavenPackage.created_at} | ${null}
|
||||
${'published'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'package'} | ${'Published to the baz project Terraform Module Registry'} | ${mavenPackage.created_at} | ${null}
|
||||
${'archived'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'history'} | ${'Package has 1 archived update'} | ${null} | ${null}
|
||||
${'archived'} | ${HISTORY_PIPELINES_LIMIT + 3} | ${'history'} | ${'Package has 2 archived updates'} | ${null} | ${null}
|
||||
${'pipeline-entry'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'pencil'} | ${'Package updated by commit sha-baz on branch branch-name, built by pipeline #3, and published to the registry'} | ${mavenPackage.created_at} | ${mockPipelineInfo.project.commit_url}
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@ describe('FollowersTab', () => {
|
|||
loading: false,
|
||||
page: 1,
|
||||
totalItems: 50,
|
||||
currentUserEmptyStateTitle: 'UserProfile|You do not have any followers.',
|
||||
visitorEmptyStateTitle: "UserProfile|This user doesn't have any followers.",
|
||||
currentUserEmptyStateTitle: 'UserProfile|You do not have any followers',
|
||||
visitorEmptyStateTitle: "UserProfile|This user doesn't have any followers",
|
||||
};
|
||||
|
||||
const defaultProvide = {
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ describe('commits service', () => {
|
|||
|
||||
beforeEach(() => {
|
||||
mock = new MockAdapter(axios);
|
||||
window.gon.features = { encodingLogsTree: true };
|
||||
mock.onGet(url).reply(HTTP_STATUS_OK, [], {});
|
||||
|
||||
jest.spyOn(axios, 'get');
|
||||
|
|
@ -56,19 +55,6 @@ describe('commits service', () => {
|
|||
expect(axios.get).toHaveBeenCalledWith(encodedUrl, expect.anything());
|
||||
});
|
||||
|
||||
describe('when encodingLogsTree FF is off', () => {
|
||||
beforeEach(() => {
|
||||
window.gon.features = {};
|
||||
});
|
||||
|
||||
it('encodes the path and ref with encodeURIComponent', async () => {
|
||||
const encodedRef = encodeURIComponent(refWithSpecialCharMock);
|
||||
const encodedUrl = `/some-project/-/refs/${encodedRef}/logs_tree/with%20%24peci%40l%20ch%40rs%2F`;
|
||||
await requestCommits(1, 'some-project', 'with $peci@l ch@rs/', refWithSpecialCharMock);
|
||||
expect(axios.get).toHaveBeenCalledWith(encodedUrl, expect.anything());
|
||||
});
|
||||
});
|
||||
|
||||
it('calls axios get once per batch', async () => {
|
||||
await Promise.all([requestCommits(0), requestCommits(1), requestCommits(23)]);
|
||||
|
||||
|
|
|
|||
|
|
@ -177,6 +177,7 @@ describe('OrganizationSelect', () => {
|
|||
|
||||
it('calls graphQL query correct `after` variable', () => {
|
||||
expect(getCurrentUserOrganizationsQueryMultiplePagesHandler).toHaveBeenCalledWith({
|
||||
search: '',
|
||||
after: pageInfo.endCursor,
|
||||
first: DEFAULT_PER_PAGE,
|
||||
});
|
||||
|
|
@ -184,6 +185,26 @@ describe('OrganizationSelect', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('when listbox is searched', () => {
|
||||
const searchTerm = 'foo';
|
||||
|
||||
beforeEach(async () => {
|
||||
createComponent();
|
||||
openListbox();
|
||||
await waitForPromises();
|
||||
|
||||
findListbox().vm.$emit('search', searchTerm);
|
||||
});
|
||||
|
||||
it('calls graphQL query with search term', () => {
|
||||
expect(getCurrentUserOrganizationsQueryHandler).toHaveBeenCalledWith({
|
||||
search: searchTerm,
|
||||
after: null,
|
||||
first: DEFAULT_PER_PAGE,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('shows an error when fetching organizations fails', async () => {
|
||||
createComponent({
|
||||
handlers: [[getCurrentUserOrganizationsQuery, jest.fn().mockRejectedValueOnce()]],
|
||||
|
|
|
|||
|
|
@ -131,6 +131,12 @@ describe('User select dropdown', () => {
|
|||
expect(participantsQueryHandlerSuccess).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('skips the participant query if `iid` is not defined', () => {
|
||||
createComponent({ props: { iid: null } });
|
||||
|
||||
expect(participantsQueryHandlerSuccess).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('emits an `error` event if participants query was rejected', async () => {
|
||||
createComponent({ participantsQueryHandler: mockError });
|
||||
await waitForPromises();
|
||||
|
|
|
|||
|
|
@ -1078,6 +1078,124 @@ RSpec.describe ProjectsHelper, feature_category: :source_code_management do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#star_count_data_attributes' do
|
||||
before do
|
||||
allow(user).to receive(:starred?).with(project).and_return(starred)
|
||||
allow(helper).to receive(:new_session_path).and_return(sign_in_path)
|
||||
allow(project).to receive(:star_count).and_return(5)
|
||||
end
|
||||
|
||||
let(:sign_in_path) { 'sign/in/path' }
|
||||
let(:common_data_attributes) do
|
||||
{
|
||||
project_id: project.id,
|
||||
sign_in_path: sign_in_path,
|
||||
star_count: 5,
|
||||
starrers_path: "/#{project.full_path}/-/starrers"
|
||||
}
|
||||
end
|
||||
|
||||
subject { helper.star_count_data_attributes(project) }
|
||||
|
||||
context 'when user has already starred the project' do
|
||||
let(:starred) { true }
|
||||
let(:expected) { common_data_attributes.merge({ starred: "true" }) }
|
||||
|
||||
it { is_expected.to eq(expected) }
|
||||
end
|
||||
|
||||
context 'when user has not starred the project' do
|
||||
let(:starred) { false }
|
||||
let(:expected) { common_data_attributes.merge({ starred: "false" }) }
|
||||
|
||||
it { is_expected.to eq(expected) }
|
||||
end
|
||||
end
|
||||
|
||||
describe '#notification_data_attributes' do
|
||||
before do
|
||||
allow(helper).to receive(:help_page_path).and_return(notification_help_path)
|
||||
allow(project).to receive(:emails_disabled?).and_return(false)
|
||||
end
|
||||
|
||||
let(:notification_help_path) { 'notification/help/path' }
|
||||
let(:notification_dropdown_items) { '["global","watch","participating","mention","disabled"]' }
|
||||
|
||||
context "returns default user notification settings" do
|
||||
let(:expected) do
|
||||
{
|
||||
emails_disabled: "false",
|
||||
notification_dropdown_items: notification_dropdown_items,
|
||||
notification_help_page_path: notification_help_path,
|
||||
notification_level: "global"
|
||||
}
|
||||
end
|
||||
|
||||
subject { helper.notification_data_attributes(project) }
|
||||
|
||||
it { is_expected.to eq(expected) }
|
||||
end
|
||||
|
||||
context "returns configured users notification settings" do
|
||||
before do
|
||||
allow(project).to receive(:emails_disabled?).and_return(true)
|
||||
setting = user.notification_settings_for(project)
|
||||
setting.level = :watch
|
||||
setting.save!
|
||||
end
|
||||
|
||||
let(:expected) do
|
||||
{
|
||||
emails_disabled: "true",
|
||||
notification_dropdown_items: notification_dropdown_items,
|
||||
notification_help_page_path: notification_help_path,
|
||||
notification_level: "watch"
|
||||
}
|
||||
end
|
||||
|
||||
subject { helper.notification_data_attributes(project) }
|
||||
|
||||
it { is_expected.to eq(expected) }
|
||||
end
|
||||
end
|
||||
|
||||
describe '#home_panel_data_attributes' do
|
||||
using RSpec::Parameterized::TableSyntax
|
||||
|
||||
before do
|
||||
allow(helper).to receive(:groups_projects_more_actions_dropdown_data).and_return(nil)
|
||||
allow(helper).to receive(:fork_button_data_attributes).and_return(nil)
|
||||
allow(helper).to receive(:notification_data_attributes).and_return(nil)
|
||||
allow(helper).to receive(:star_count_data_attributes).and_return({})
|
||||
end
|
||||
|
||||
where(:can_read_project, :is_empty_repo) do
|
||||
true | true
|
||||
false | false
|
||||
end
|
||||
|
||||
with_them do
|
||||
context "returns default user project details" do
|
||||
before do
|
||||
allow(helper).to receive(:can?).with(user, :read_project, project).and_return(can_read_project)
|
||||
allow(project).to receive(:empty_repo?).and_return(is_empty_repo)
|
||||
end
|
||||
|
||||
let(:expected) do
|
||||
{
|
||||
can_read_project: can_read_project.to_s,
|
||||
is_project_empty: is_empty_repo.to_s,
|
||||
project_id: project.id
|
||||
}
|
||||
end
|
||||
|
||||
subject { helper.home_panel_data_attributes }
|
||||
|
||||
it { is_expected.to eq(expected) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'configure import method modal' do
|
||||
context 'as a user' do
|
||||
it 'returns a link to contact an administrator' do
|
||||
|
|
|
|||
|
|
@ -408,7 +408,7 @@ RSpec.describe BulkImports::Entity, type: :model, feature_category: :importers d
|
|||
end
|
||||
|
||||
describe '#full_path' do
|
||||
it 'returns group full path for project entity' do
|
||||
it 'returns group full path for group entity' do
|
||||
group_entity = build(:bulk_import_entity, :group_entity, group: build(:group))
|
||||
|
||||
expect(group_entity.full_path).to eq(group_entity.group.full_path)
|
||||
|
|
@ -427,6 +427,26 @@ RSpec.describe BulkImports::Entity, type: :model, feature_category: :importers d
|
|||
end
|
||||
end
|
||||
|
||||
describe '#full_path_with_fallback' do
|
||||
it 'returns group full path for group entity' do
|
||||
group_entity = build(:bulk_import_entity, :group_entity, group: build(:group))
|
||||
|
||||
expect(group_entity.full_path_with_fallback).to eq(group_entity.group.full_path)
|
||||
end
|
||||
|
||||
it 'returns project full path for project entity' do
|
||||
project_entity = build(:bulk_import_entity, :project_entity, project: build(:project))
|
||||
|
||||
expect(project_entity.full_path_with_fallback).to eq(project_entity.project.full_path)
|
||||
end
|
||||
|
||||
it 'returns fallback full path when not associated with group or project' do
|
||||
entity = build(:bulk_import_entity, group: nil, project: nil)
|
||||
|
||||
expect(entity.full_path_with_fallback).to eq("#{entity.destination_namespace}/#{entity.destination_slug}")
|
||||
end
|
||||
end
|
||||
|
||||
describe '#default_visibility_level' do
|
||||
context 'when entity is a group' do
|
||||
it 'returns default group visibility' do
|
||||
|
|
|
|||
|
|
@ -216,16 +216,11 @@ RSpec.configure do |config|
|
|||
# This includes the first try, i.e. tests will be run 2 times before failing.
|
||||
config.default_retry_count = ENV.fetch('RETRIES', 1).to_i + 1
|
||||
|
||||
# Do not retry controller tests because rspec-retry cannot properly
|
||||
# reset the controller which may contain data from last attempt. See
|
||||
# https://gitlab.com/gitlab-org/gitlab/-/merge_requests/73360
|
||||
config.prepend_before(:each, type: :controller) do |example|
|
||||
example.metadata[:retry] = 1
|
||||
end
|
||||
|
||||
# Gradually stop using rspec-retry
|
||||
# See https://gitlab.com/gitlab-org/gitlab/-/issues/438388
|
||||
%i[
|
||||
bin channels commands components config contracts controller db
|
||||
dependencies dot_gitlab_ci experiments finders
|
||||
graphql haml_lint helpers initializers keeps lib mailers metrics_server
|
||||
migrations models policies presenters rack_servers requests
|
||||
routing rubocop scripts serializers services sidekiq sidekiq_cluster
|
||||
|
|
|
|||
|
|
@ -29,8 +29,8 @@ module CycleAnalyticsHelpers
|
|||
|
||||
def select_event_label(sel)
|
||||
page.within(sel) do
|
||||
find('.dropdown-toggle').click
|
||||
page.find(".dropdown-menu").all(".dropdown-item")[1].click
|
||||
find('[data-testid="base-dropdown-toggle"]').click
|
||||
page.find('[data-testid="base-dropdown-menu"]').all(".gl-new-dropdown-item")[1].click
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ RSpec.shared_examples 'variable list pagination' do |variable_type|
|
|||
end
|
||||
|
||||
page.within('[data-testid="ci-variable-table"]') do
|
||||
find('.b-table-sort-icon-left').click
|
||||
find('[aria-sort="ascending"]').click
|
||||
end
|
||||
|
||||
wait_for_requests
|
||||
|
|
|
|||
|
|
@ -37,44 +37,17 @@ RSpec.describe 'projects/_home_panel' do
|
|||
end
|
||||
end
|
||||
|
||||
context 'notifications' do
|
||||
context 'home panel' do
|
||||
let(:project) { create(:project) }
|
||||
|
||||
before do
|
||||
assign(:project, project)
|
||||
|
||||
allow(view).to receive(:current_user).and_return(user)
|
||||
allow(view).to receive(:can?).with(user, :read_project, project).and_return(false)
|
||||
allow(project).to receive(:license_anchor_data).and_return(false)
|
||||
end
|
||||
|
||||
context 'when user is signed in' do
|
||||
let(:user) { create(:user) }
|
||||
it 'renders Vue app root' do
|
||||
render
|
||||
|
||||
before do
|
||||
notification_settings = user.notification_settings_for(project)
|
||||
assign(:notification_setting, notification_settings)
|
||||
end
|
||||
|
||||
it 'renders Vue app root' do
|
||||
render
|
||||
|
||||
expect(rendered).to have_selector('.js-vue-notification-dropdown')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is signed out' do
|
||||
let(:user) { nil }
|
||||
|
||||
before do
|
||||
assign(:notification_setting, nil)
|
||||
end
|
||||
|
||||
it 'does not render Vue app root' do
|
||||
render
|
||||
|
||||
expect(rendered).not_to have_selector('.js-vue-notification-dropdown')
|
||||
end
|
||||
expect(rendered).to have_selector('#js-home-panel')
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ RSpec.describe 'shared/projects/_list' do
|
|||
it 'renders a no-content message' do
|
||||
render
|
||||
|
||||
expect(rendered).to have_content(s_('UserProfile|Explore public groups to find projects to contribute to.'))
|
||||
expect(rendered).to have_content(s_('UserProfile|Explore public groups to find projects to contribute to'))
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -95,7 +95,7 @@ RSpec.describe 'shared/projects/_list' do
|
|||
it 'renders a no-content message' do
|
||||
render
|
||||
|
||||
expect(rendered).to have_content(s_('UserProfile|There are no projects available to be displayed here.'))
|
||||
expect(rendered).to have_content(s_('UserProfile|There are no projects available to be displayed here'))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1326,10 +1326,10 @@
|
|||
resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-3.84.0.tgz#4c251a528c825875b3062be236ae2a06569c9f45"
|
||||
integrity sha512-v6Sh3VRVTelWY+yPJ/kWm1A4y0Ox1xgecXljVd7BpB0S9OboK2J5AXbwzqit6s4TSab/B8G3Vf5g4fHsVQCXqg==
|
||||
|
||||
"@gitlab/ui@^74.9.1":
|
||||
version "74.9.1"
|
||||
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-74.9.1.tgz#0500fcc3b50d373e391eaf959f44166050c35c5e"
|
||||
integrity sha512-itEFQUgqfl3l/5lBOtBTpIWbu3DyEH9YsBDbgtouxOlWammEi/DmW+dQ45DzeHrJdkbfzGW2fwLd4mn1i89Mew==
|
||||
"@gitlab/ui@^74.9.3":
|
||||
version "74.9.3"
|
||||
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-74.9.3.tgz#c78e7962f9abd35134680c8e5f68e40565a27a9b"
|
||||
integrity sha512-HoIPtsMaQ/Qj2DEX6AqJSWD+CPFAOxw1b1b/jGLQKJHwvR02ff+CNgE4Gv3luCfOVWlEwIiZfLwIorACZG6flg==
|
||||
dependencies:
|
||||
"@floating-ui/dom" "1.4.3"
|
||||
bootstrap-vue "2.23.1"
|
||||
|
|
|
|||
Loading…
Reference in New Issue