summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-03-07 21:13:36 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2023-03-07 21:13:36 +0000
commitc19944d9970b788d8523cee6ee05217a8afd7646 (patch)
treee2d15e8c0d541b9b2fe26b9b82f23661df120f94 /app
parent3ff3d897d6529aabb21aa6aed54eb430a9cf0fe2 (diff)
downloadgitlab-ce-c19944d9970b788d8523cee6ee05217a8afd7646.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/authentication/webauthn/authenticate.js3
-rw-r--r--app/assets/javascripts/authentication/webauthn/components/registration.vue4
-rw-r--r--app/assets/javascripts/authentication/webauthn/constants.js2
-rw-r--r--app/assets/javascripts/authentication/webauthn/error.js7
-rw-r--r--app/assets/javascripts/authentication/webauthn/register.js3
-rw-r--r--app/assets/javascripts/authentication/webauthn/util.js3
-rw-r--r--app/assets/javascripts/issues/create_merge_request_dropdown.js2
-rw-r--r--app/assets/javascripts/issues/issue.js2
-rw-r--r--app/assets/javascripts/issues/list/components/issues_list_app.vue2
-rw-r--r--app/assets/javascripts/issues/manual_ordering.js2
-rw-r--r--app/assets/javascripts/issues/related_merge_requests/store/actions.js2
-rw-r--r--app/assets/javascripts/issues/show/components/app.vue15
-rw-r--r--app/assets/javascripts/issues/show/components/description.vue2
-rw-r--r--app/assets/javascripts/issues/show/components/header_actions.vue2
-rw-r--r--app/assets/javascripts/issues/show/components/incidents/create_timeline_event.vue2
-rw-r--r--app/assets/javascripts/issues/show/components/incidents/incident_tabs.vue2
-rw-r--r--app/assets/javascripts/issues/show/components/incidents/timeline_events_list.vue2
-rw-r--r--app/assets/javascripts/issues/show/components/incidents/utils.js2
-rw-r--r--app/assets/javascripts/pages/groups/new/components/app.vue9
-rw-r--r--app/assets/javascripts/pages/groups/new/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/commit/show/index.js2
-rw-r--r--app/assets/javascripts/pages/users/activity_calendar.js2
-rw-r--r--app/assets/javascripts/pages/users/user_tabs.js2
-rw-r--r--app/assets/javascripts/projects/new/components/app.vue10
-rw-r--r--app/assets/javascripts/projects/new/index.js2
-rw-r--r--app/assets/javascripts/vue_shared/alert_details/components/system_notes/system_note.vue6
-rw-r--r--app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/branch_token.vue2
-rw-r--r--app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/crm_contact_token.vue2
-rw-r--r--app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/release_token.vue2
-rw-r--r--app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/user_token.vue2
-rw-r--r--app/assets/javascripts/vue_shared/components/user_popover/user_popover.vue2
-rw-r--r--app/assets/javascripts/vue_shared/security_reports/components/artifact_downloads/merge_request_artifact_download.vue2
-rw-r--r--app/assets/javascripts/vue_shared/security_reports/security_reports_app.vue2
-rw-r--r--app/graphql/mutations/design_management/update.rb39
-rw-r--r--app/graphql/types/design_management/design_type.rb7
-rw-r--r--app/graphql/types/mutation_type.rb1
-rw-r--r--app/policies/issue_policy.rb1
-rw-r--r--app/policies/project_policy.rb2
-rw-r--r--app/services/resource_access_tokens/create_service.rb28
-rw-r--r--app/views/groups/new.html.haml2
-rw-r--r--app/views/projects/new.html.haml10
41 files changed, 135 insertions, 63 deletions
diff --git a/app/assets/javascripts/authentication/webauthn/authenticate.js b/app/assets/javascripts/authentication/webauthn/authenticate.js
index 47cb7a40f76..748945a680b 100644
--- a/app/assets/javascripts/authentication/webauthn/authenticate.js
+++ b/app/assets/javascripts/authentication/webauthn/authenticate.js
@@ -1,3 +1,4 @@
+import { WEBAUTHN_AUTHENTICATE } from './constants';
import WebAuthnError from './error';
import WebAuthnFlow from './flow';
import { supported, convertGetParams, convertGetResponse } from './util';
@@ -44,7 +45,7 @@ export default class WebAuthnAuthenticate {
this.renderAuthenticated(JSON.stringify(convertedResponse));
})
.catch((err) => {
- this.flow.renderError(new WebAuthnError(err, 'authenticate'));
+ this.flow.renderError(new WebAuthnError(err, WEBAUTHN_AUTHENTICATE));
});
}
diff --git a/app/assets/javascripts/authentication/webauthn/components/registration.vue b/app/assets/javascripts/authentication/webauthn/components/registration.vue
index 1cc57046562..9a3644e0325 100644
--- a/app/assets/javascripts/authentication/webauthn/components/registration.vue
+++ b/app/assets/javascripts/authentication/webauthn/components/registration.vue
@@ -30,10 +30,10 @@ import {
STATE_UNSUPPORTED,
STATE_WAITING,
WEBAUTHN_DOCUMENTATION_PATH,
+ WEBAUTHN_REGISTER,
} from '~/authentication/webauthn/constants';
import WebAuthnError from '~/authentication/webauthn/error';
import {
- FLOW_REGISTER,
convertCreateParams,
convertCreateResponse,
isHTTPS,
@@ -123,7 +123,7 @@ export default {
this.credentials = JSON.stringify(convertCreateResponse(credentials));
this.state = STATE_SUCCESS;
} catch (error) {
- this.errorMessage = new WebAuthnError(error, FLOW_REGISTER).message();
+ this.errorMessage = new WebAuthnError(error, WEBAUTHN_REGISTER).message();
this.state = STATE_ERROR;
}
},
diff --git a/app/assets/javascripts/authentication/webauthn/constants.js b/app/assets/javascripts/authentication/webauthn/constants.js
index 6646cb2eb3f..c41e6d2bd58 100644
--- a/app/assets/javascripts/authentication/webauthn/constants.js
+++ b/app/assets/javascripts/authentication/webauthn/constants.js
@@ -38,6 +38,8 @@ export const STATE_SUCCESS = 'success';
export const STATE_UNSUPPORTED = 'unsupported';
export const STATE_WAITING = 'waiting';
+export const WEBAUTHN_AUTHENTICATE = 'authenticate';
+export const WEBAUTHN_REGISTER = 'register';
export const WEBAUTHN_DOCUMENTATION_PATH = helpPagePath(
'user/profile/account/two_factor_authentication',
{ anchor: 'set-up-a-webauthn-device' },
diff --git a/app/assets/javascripts/authentication/webauthn/error.js b/app/assets/javascripts/authentication/webauthn/error.js
index a1a3f861c25..40dbecd8bc9 100644
--- a/app/assets/javascripts/authentication/webauthn/error.js
+++ b/app/assets/javascripts/authentication/webauthn/error.js
@@ -1,5 +1,6 @@
import { __ } from '~/locale';
-import { isHTTPS, FLOW_AUTHENTICATE, FLOW_REGISTER } from './util';
+import { WEBAUTHN_AUTHENTICATE, WEBAUTHN_REGISTER } from './constants';
+import { isHTTPS } from './util';
export default class WebAuthnError {
constructor(error, flowType) {
@@ -13,9 +14,9 @@ export default class WebAuthnError {
message() {
if (this.errorName === 'NotSupportedError') {
return __('Your device is not compatible with GitLab. Please try another device');
- } else if (this.errorName === 'InvalidStateError' && this.flowType === FLOW_AUTHENTICATE) {
+ } else if (this.errorName === 'InvalidStateError' && this.flowType === WEBAUTHN_AUTHENTICATE) {
return __('This device has not been registered with us.');
- } else if (this.errorName === 'InvalidStateError' && this.flowType === FLOW_REGISTER) {
+ } else if (this.errorName === 'InvalidStateError' && this.flowType === WEBAUTHN_REGISTER) {
return __('This device has already been registered with us.');
} else if (this.errorName === 'SecurityError' && this.httpsDisabled) {
return __(
diff --git a/app/assets/javascripts/authentication/webauthn/register.js b/app/assets/javascripts/authentication/webauthn/register.js
index 62ebf85abe4..c00d3ede2c1 100644
--- a/app/assets/javascripts/authentication/webauthn/register.js
+++ b/app/assets/javascripts/authentication/webauthn/register.js
@@ -2,6 +2,7 @@ import { __ } from '~/locale';
import WebAuthnError from './error';
import WebAuthnFlow from './flow';
import { supported, isHTTPS, convertCreateParams, convertCreateResponse } from './util';
+import { WEBAUTHN_REGISTER } from './constants';
// Register WebAuthn devices for users to authenticate with.
//
@@ -40,7 +41,7 @@ export default class WebAuthnRegister {
publicKey: this.webauthnOptions,
})
.then((cred) => this.renderRegistered(JSON.stringify(convertCreateResponse(cred))))
- .catch((err) => this.flow.renderError(new WebAuthnError(err, 'register')));
+ .catch((err) => this.flow.renderError(new WebAuthnError(err, WEBAUTHN_REGISTER)));
}
renderSetup() {
diff --git a/app/assets/javascripts/authentication/webauthn/util.js b/app/assets/javascripts/authentication/webauthn/util.js
index 4e1409b9ed9..0ff0f0e6a29 100644
--- a/app/assets/javascripts/authentication/webauthn/util.js
+++ b/app/assets/javascripts/authentication/webauthn/util.js
@@ -8,9 +8,6 @@ export function isHTTPS() {
return window.location.protocol.startsWith('https');
}
-export const FLOW_AUTHENTICATE = 'authenticate';
-export const FLOW_REGISTER = 'register';
-
/**
* Converts a base64 string to an ArrayBuffer
*
diff --git a/app/assets/javascripts/issues/create_merge_request_dropdown.js b/app/assets/javascripts/issues/create_merge_request_dropdown.js
index caf82e482ea..c821c18bcb9 100644
--- a/app/assets/javascripts/issues/create_merge_request_dropdown.js
+++ b/app/assets/javascripts/issues/create_merge_request_dropdown.js
@@ -7,7 +7,7 @@ import {
import confidentialMergeRequestState from '~/confidential_merge_request/state';
import DropLab from '~/filtered_search/droplab/drop_lab_deprecated';
import ISetter from '~/filtered_search/droplab/plugins/input_setter';
-import { createAlert } from '~/flash';
+import { createAlert } from '~/alert';
import axios from '~/lib/utils/axios_utils';
import { __, sprintf } from '~/locale';
import { mergeUrlParams } from '~/lib/utils/url_utility';
diff --git a/app/assets/javascripts/issues/issue.js b/app/assets/javascripts/issues/issue.js
index de1c689e590..b7fd99d8042 100644
--- a/app/assets/javascripts/issues/issue.js
+++ b/app/assets/javascripts/issues/issue.js
@@ -1,6 +1,6 @@
import $ from 'jquery';
import { joinPaths } from '~/lib/utils/url_utility';
-import { createAlert } from '~/flash';
+import { createAlert } from '~/alert';
import { EVENT_ISSUABLE_VUE_APP_CHANGE } from '~/issuable/constants';
import axios from '~/lib/utils/axios_utils';
import { addDelimiter } from '~/lib/utils/text_utility';
diff --git a/app/assets/javascripts/issues/list/components/issues_list_app.vue b/app/assets/javascripts/issues/list/components/issues_list_app.vue
index 35727566fba..f03ecdc4125 100644
--- a/app/assets/javascripts/issues/list/components/issues_list_app.vue
+++ b/app/assets/javascripts/issues/list/components/issues_list_app.vue
@@ -7,7 +7,7 @@ import IssueCardStatistics from 'ee_else_ce/issues/list/components/issue_card_st
import IssueCardTimeInfo from 'ee_else_ce/issues/list/components/issue_card_time_info.vue';
import getIssuesQuery from 'ee_else_ce/issues/list/queries/get_issues.query.graphql';
import getIssuesCountsQuery from 'ee_else_ce/issues/list/queries/get_issues_counts.query.graphql';
-import { createAlert, VARIANT_INFO } from '~/flash';
+import { createAlert, VARIANT_INFO } from '~/alert';
import { TYPENAME_USER } from '~/graphql_shared/constants';
import { convertToGraphQLId, getIdFromGraphQLId } from '~/graphql_shared/utils';
import CsvImportExportButtons from '~/issuable/components/csv_import_export_buttons.vue';
diff --git a/app/assets/javascripts/issues/manual_ordering.js b/app/assets/javascripts/issues/manual_ordering.js
index 1bb53dfd50d..f22062cf048 100644
--- a/app/assets/javascripts/issues/manual_ordering.js
+++ b/app/assets/javascripts/issues/manual_ordering.js
@@ -1,5 +1,5 @@
import Sortable from 'sortablejs';
-import { createAlert } from '~/flash';
+import { createAlert } from '~/alert';
import axios from '~/lib/utils/axios_utils';
import { s__ } from '~/locale';
import { getSortableDefaultOptions, sortableStart } from '~/sortable/utils';
diff --git a/app/assets/javascripts/issues/related_merge_requests/store/actions.js b/app/assets/javascripts/issues/related_merge_requests/store/actions.js
index 4c81f1d9bc1..ad5b61424dc 100644
--- a/app/assets/javascripts/issues/related_merge_requests/store/actions.js
+++ b/app/assets/javascripts/issues/related_merge_requests/store/actions.js
@@ -1,4 +1,4 @@
-import { createAlert } from '~/flash';
+import { createAlert } from '~/alert';
import axios from '~/lib/utils/axios_utils';
import { normalizeHeaders } from '~/lib/utils/common_utils';
import { __ } from '~/locale';
diff --git a/app/assets/javascripts/issues/show/components/app.vue b/app/assets/javascripts/issues/show/components/app.vue
index 0be11c5c537..851808b628e 100644
--- a/app/assets/javascripts/issues/show/components/app.vue
+++ b/app/assets/javascripts/issues/show/components/app.vue
@@ -1,7 +1,7 @@
<script>
import { GlIcon, GlBadge, GlIntersectionObserver, GlTooltipDirective } from '@gitlab/ui';
import Visibility from 'visibilityjs';
-import { createAlert } from '~/flash';
+import { createAlert } from '~/alert';
import {
IssuableStatusText,
STATUS_CLOSED,
@@ -277,7 +277,7 @@ export default {
},
},
created() {
- this.flashContainer = null;
+ this.alert = null;
this.service = new Service(this.endpoint);
this.poll = new Poll({
resource: this.service,
@@ -395,7 +395,7 @@ export default {
? { ...formState, issue_type: issueState.issueType }
: formState;
- this.clearFlash();
+ this.alert?.dismiss();
return this.service
.updateIssuable(issuablePayload)
@@ -431,7 +431,7 @@ export default {
errMsg += `. ${message}`;
}
- this.flashContainer = createAlert({
+ this.alert = createAlert({
message: errMsg,
});
})
@@ -448,13 +448,6 @@ export default {
this.isStickyHeaderShowing = true;
},
- clearFlash() {
- if (this.flashContainer) {
- this.flashContainer.close();
- this.flashContainer = null;
- }
- },
-
handleSaveDescription(description) {
this.updateFormState();
this.setFormState({ description });
diff --git a/app/assets/javascripts/issues/show/components/description.vue b/app/assets/javascripts/issues/show/components/description.vue
index b36a456f41b..6e072e12bd9 100644
--- a/app/assets/javascripts/issues/show/components/description.vue
+++ b/app/assets/javascripts/issues/show/components/description.vue
@@ -7,7 +7,7 @@ import getIssueDetailsQuery from 'ee_else_ce/work_items/graphql/get_issue_detail
import SafeHtml from '~/vue_shared/directives/safe_html';
import { convertToGraphQLId } from '~/graphql_shared/utils';
import { TYPENAME_ISSUE, TYPENAME_WORK_ITEM } from '~/graphql_shared/constants';
-import { createAlert } from '~/flash';
+import { createAlert } from '~/alert';
import { TYPE_ISSUE } from '~/issues/constants';
import { __, s__, sprintf } from '~/locale';
import { getSortableDefaultOptions, isDragging } from '~/sortable/utils';
diff --git a/app/assets/javascripts/issues/show/components/header_actions.vue b/app/assets/javascripts/issues/show/components/header_actions.vue
index d77cb1fa1c2..ba986bd0020 100644
--- a/app/assets/javascripts/issues/show/components/header_actions.vue
+++ b/app/assets/javascripts/issues/show/components/header_actions.vue
@@ -10,7 +10,7 @@ import {
GlTooltipDirective,
} from '@gitlab/ui';
import { mapActions, mapGetters, mapState } from 'vuex';
-import { createAlert, VARIANT_SUCCESS } from '~/flash';
+import { createAlert, VARIANT_SUCCESS } from '~/alert';
import { EVENT_ISSUABLE_VUE_APP_CHANGE } from '~/issuable/constants';
import { STATUS_CLOSED, TYPE_INCIDENT, TYPE_ISSUE } from '~/issues/constants';
import { ISSUE_STATE_EVENT_CLOSE, ISSUE_STATE_EVENT_REOPEN } from '~/issues/show/constants';
diff --git a/app/assets/javascripts/issues/show/components/incidents/create_timeline_event.vue b/app/assets/javascripts/issues/show/components/incidents/create_timeline_event.vue
index c2b7d33c14c..ac64c35bf15 100644
--- a/app/assets/javascripts/issues/show/components/incidents/create_timeline_event.vue
+++ b/app/assets/javascripts/issues/show/components/incidents/create_timeline_event.vue
@@ -3,7 +3,7 @@ import { produce } from 'immer';
import { sortBy } from 'lodash';
import { GlIcon } from '@gitlab/ui';
import { sprintf } from '~/locale';
-import { createAlert } from '~/flash';
+import { createAlert } from '~/alert';
import { convertToGraphQLId } from '~/graphql_shared/utils';
import { TYPENAME_ISSUE } from '~/graphql_shared/constants';
import { timelineFormI18n } from './constants';
diff --git a/app/assets/javascripts/issues/show/components/incidents/incident_tabs.vue b/app/assets/javascripts/issues/show/components/incidents/incident_tabs.vue
index 1c677c0d9e6..4ec64ef838d 100644
--- a/app/assets/javascripts/issues/show/components/incidents/incident_tabs.vue
+++ b/app/assets/javascripts/issues/show/components/incidents/incident_tabs.vue
@@ -1,6 +1,6 @@
<script>
import { GlTab, GlTabs } from '@gitlab/ui';
-import { createAlert } from '~/flash';
+import { createAlert } from '~/alert';
import { trackIncidentDetailsViewsOptions } from '~/incidents/constants';
import { s__ } from '~/locale';
import Tracking from '~/tracking';
diff --git a/app/assets/javascripts/issues/show/components/incidents/timeline_events_list.vue b/app/assets/javascripts/issues/show/components/incidents/timeline_events_list.vue
index 10b80529a66..5aef4b1b809 100644
--- a/app/assets/javascripts/issues/show/components/incidents/timeline_events_list.vue
+++ b/app/assets/javascripts/issues/show/components/incidents/timeline_events_list.vue
@@ -1,6 +1,6 @@
<script>
import { formatDate } from '~/lib/utils/datetime_utility';
-import { createAlert } from '~/flash';
+import { createAlert } from '~/alert';
import { sprintf } from '~/locale';
import { confirmAction } from '~/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal';
import { ignoreWhilePending } from '~/lib/utils/ignore_while_pending';
diff --git a/app/assets/javascripts/issues/show/components/incidents/utils.js b/app/assets/javascripts/issues/show/components/incidents/utils.js
index ce33e91c3b8..2072961ce29 100644
--- a/app/assets/javascripts/issues/show/components/incidents/utils.js
+++ b/app/assets/javascripts/issues/show/components/incidents/utils.js
@@ -1,4 +1,4 @@
-import { createAlert } from '~/flash';
+import { createAlert } from '~/alert';
import { s__ } from '~/locale';
export const displayAndLogError = (error) =>
diff --git a/app/assets/javascripts/pages/groups/new/components/app.vue b/app/assets/javascripts/pages/groups/new/components/app.vue
index 68f813d9375..38fb96d40b7 100644
--- a/app/assets/javascripts/pages/groups/new/components/app.vue
+++ b/app/assets/javascripts/pages/groups/new/components/app.vue
@@ -11,6 +11,10 @@ export default {
NewNamespacePage,
},
props: {
+ groupsUrl: {
+ type: String,
+ required: true,
+ },
parentGroupUrl: {
type: String,
required: false,
@@ -39,7 +43,10 @@ export default {
{ text: this.parentGroupName, href: this.parentGroupUrl },
{ text: s__('GroupsNew|New subgroup'), href: '#' },
]
- : [{ text: s__('GroupsNew|New group'), href: '#' }];
+ : [
+ { text: s__('GroupsNew|Groups'), href: this.groupsUrl },
+ { text: s__('GroupsNew|New group'), href: '#' },
+ ];
},
panels() {
return [
diff --git a/app/assets/javascripts/pages/groups/new/index.js b/app/assets/javascripts/pages/groups/new/index.js
index acaee097dc1..b16c5f3da9f 100644
--- a/app/assets/javascripts/pages/groups/new/index.js
+++ b/app/assets/javascripts/pages/groups/new/index.js
@@ -22,6 +22,7 @@ initFilePickers();
function initNewGroupCreation(el) {
const {
hasErrors,
+ groupsUrl,
parentGroupUrl,
parentGroupName,
importExistingGroupPath,
@@ -31,6 +32,7 @@ function initNewGroupCreation(el) {
} = el.dataset;
const props = {
+ groupsUrl,
parentGroupUrl,
parentGroupName,
importExistingGroupPath,
diff --git a/app/assets/javascripts/pages/projects/commit/show/index.js b/app/assets/javascripts/pages/projects/commit/show/index.js
index 3a293956089..f871cd804e7 100644
--- a/app/assets/javascripts/pages/projects/commit/show/index.js
+++ b/app/assets/javascripts/pages/projects/commit/show/index.js
@@ -4,7 +4,7 @@ import Vue from 'vue';
import loadAwardsHandler from '~/awards_handler';
import ShortcutsNavigation from '~/behaviors/shortcuts/shortcuts_navigation';
import Diff from '~/diff';
-import { createAlert } from '~/flash';
+import { createAlert } from '~/alert';
import initDeprecatedNotes from '~/init_deprecated_notes';
import { initDiffStatsDropdown } from '~/init_diff_stats_dropdown';
import axios from '~/lib/utils/axios_utils';
diff --git a/app/assets/javascripts/pages/users/activity_calendar.js b/app/assets/javascripts/pages/users/activity_calendar.js
index 6f7ce7d59c3..b52b7ed4caa 100644
--- a/app/assets/javascripts/pages/users/activity_calendar.js
+++ b/app/assets/javascripts/pages/users/activity_calendar.js
@@ -184,6 +184,7 @@ export default class ActivityCalendar {
});
return `translate(${this.daySizeWithSpace * i + 1 + this.daySizeWithSpace}, 18)`;
})
+ .attr('data-testid', 'user-contrib-cell-group')
.selectAll('rect')
.data((stamp) => stamp)
.enter()
@@ -195,6 +196,7 @@ export default class ActivityCalendar {
.attr('data-level', (stamp) => getLevelFromContributions(stamp.count))
.attr('title', (stamp) => formatTooltipText(stamp))
.attr('class', 'user-contrib-cell has-tooltip')
+ .attr('data-testid', 'user-contrib-cell')
.attr('data-html', true)
.attr('data-container', 'body')
.on('click', this.clickDay);
diff --git a/app/assets/javascripts/pages/users/user_tabs.js b/app/assets/javascripts/pages/users/user_tabs.js
index 3a23f9ff49c..430022f9a9b 100644
--- a/app/assets/javascripts/pages/users/user_tabs.js
+++ b/app/assets/javascripts/pages/users/user_tabs.js
@@ -253,7 +253,7 @@ export default class UserTabs {
timestamps: data,
calendarActivitiesPath,
utcOffset,
- firstDayOfTheWeek: gon.first_day_of_week,
+ firstDayOfWeek: gon.first_day_of_week,
monthsAgo,
});
}
diff --git a/app/assets/javascripts/projects/new/components/app.vue b/app/assets/javascripts/projects/new/components/app.vue
index 8d883e7126c..251db16d8e3 100644
--- a/app/assets/javascripts/projects/new/components/app.vue
+++ b/app/assets/javascripts/projects/new/components/app.vue
@@ -59,6 +59,10 @@ export default {
SafeHtml,
},
props: {
+ projectsUrl: {
+ type: String,
+ required: true,
+ },
parentGroupUrl: {
type: String,
required: false,
@@ -89,9 +93,11 @@ export default {
computed: {
initialBreadcrumbs() {
return [
- this.parentGroupUrl && { text: this.parentGroupName, href: this.parentGroupUrl },
+ this.parentGroupUrl
+ ? { text: this.parentGroupName, href: this.parentGroupUrl }
+ : { text: s__('ProjectsNew|Projects'), href: this.projectsUrl },
{ text: s__('ProjectsNew|New project'), href: '#' },
- ].filter(Boolean);
+ ];
},
availablePanels() {
return this.isCiCdAvailable ? PANELS : PANELS.filter((p) => p.name !== CI_CD_PANEL);
diff --git a/app/assets/javascripts/projects/new/index.js b/app/assets/javascripts/projects/new/index.js
index 0b190b6a88b..7330874eefe 100644
--- a/app/assets/javascripts/projects/new/index.js
+++ b/app/assets/javascripts/projects/new/index.js
@@ -17,6 +17,7 @@ export function initNewProjectCreation() {
isCiCdAvailable,
parentGroupUrl,
parentGroupName,
+ projectsUrl,
} = el.dataset;
const props = {
@@ -25,6 +26,7 @@ export function initNewProjectCreation() {
newProjectGuidelines,
parentGroupUrl,
parentGroupName,
+ projectsUrl,
};
const provide = {
diff --git a/app/assets/javascripts/vue_shared/alert_details/components/system_notes/system_note.vue b/app/assets/javascripts/vue_shared/alert_details/components/system_notes/system_note.vue
index 634b7da3def..93581dbbd40 100644
--- a/app/assets/javascripts/vue_shared/alert_details/components/system_notes/system_note.vue
+++ b/app/assets/javascripts/vue_shared/alert_details/components/system_notes/system_note.vue
@@ -33,7 +33,11 @@ export default {
</script>
<template>
- <li :id="noteAnchorId" class="timeline-entry note system-note note-wrapper gl-p-0!">
+ <li
+ :id="noteAnchorId"
+ class="timeline-entry note system-note note-wrapper gl-p-0!"
+ data-qa-selector="alert_system_note_container"
+ >
<div class="gl-display-inline-flex gl-align-items-center gl-relative">
<div
class="gl-display-inline gl-bg-white gl-text-gray-200 gl-border-gray-100 gl-border-1 gl-border-solid gl-rounded-full gl-box-sizing-content-box gl-p-3 gl-mt-n2 gl-mr-6"
diff --git a/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/branch_token.vue b/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/branch_token.vue
index 741395b3193..fff8a95c193 100644
--- a/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/branch_token.vue
+++ b/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/branch_token.vue
@@ -1,6 +1,6 @@
<script>
import { GlFilteredSearchSuggestion } from '@gitlab/ui';
-import { createAlert } from '~/flash';
+import { createAlert } from '~/alert';
import { __ } from '~/locale';
import BaseToken from '~/vue_shared/components/filtered_search_bar/tokens/base_token.vue';
diff --git a/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/crm_contact_token.vue b/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/crm_contact_token.vue
index fcabeab1d8a..63ffded9e8e 100644
--- a/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/crm_contact_token.vue
+++ b/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/crm_contact_token.vue
@@ -3,7 +3,7 @@ import { GlFilteredSearchSuggestion } from '@gitlab/ui';
import { TYPENAME_CRM_CONTACT } from '~/graphql_shared/constants';
import { getIdFromGraphQLId, convertToGraphQLId } from '~/graphql_shared/utils';
-import { createAlert } from '~/flash';
+import { createAlert } from '~/alert';
import { WORKSPACE_GROUP, WORKSPACE_PROJECT } from '~/issues/constants';
import { isPositiveInteger } from '~/lib/utils/number_utils';
import { __ } from '~/locale';
diff --git a/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/release_token.vue b/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/release_token.vue
index 6d681aab3ca..a251035b683 100644
--- a/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/release_token.vue
+++ b/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/release_token.vue
@@ -1,6 +1,6 @@
<script>
import { GlFilteredSearchSuggestion } from '@gitlab/ui';
-import { createAlert } from '~/flash';
+import { createAlert } from '~/alert';
import { __ } from '~/locale';
import BaseToken from '~/vue_shared/components/filtered_search_bar/tokens/base_token.vue';
import { OPTIONS_NONE_ANY } from '../constants';
diff --git a/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/user_token.vue b/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/user_token.vue
index 28e65c1185f..c294c23abfc 100644
--- a/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/user_token.vue
+++ b/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/user_token.vue
@@ -1,7 +1,7 @@
<script>
import { GlAvatar, GlFilteredSearchSuggestion } from '@gitlab/ui';
import { compact } from 'lodash';
-import { createAlert } from '~/flash';
+import { createAlert } from '~/alert';
import { __ } from '~/locale';
import { OPTIONS_NONE_ANY } from '../constants';
diff --git a/app/assets/javascripts/vue_shared/components/user_popover/user_popover.vue b/app/assets/javascripts/vue_shared/components/user_popover/user_popover.vue
index d06bc7b8f98..dd9d2ce66cd 100644
--- a/app/assets/javascripts/vue_shared/components/user_popover/user_popover.vue
+++ b/app/assets/javascripts/vue_shared/components/user_popover/user_popover.vue
@@ -10,7 +10,7 @@ import {
} from '@gitlab/ui';
import SafeHtml from '~/vue_shared/directives/safe_html';
import { glEmojiTag } from '~/emoji';
-import { createAlert } from '~/flash';
+import { createAlert } from '~/alert';
import { followUser, unfollowUser } from '~/rest_api';
import { isUserBusy } from '~/set_status_modal/utils';
import Tracking from '~/tracking';
diff --git a/app/assets/javascripts/vue_shared/security_reports/components/artifact_downloads/merge_request_artifact_download.vue b/app/assets/javascripts/vue_shared/security_reports/components/artifact_downloads/merge_request_artifact_download.vue
index a4fb30a03a1..4c2b082242b 100644
--- a/app/assets/javascripts/vue_shared/security_reports/components/artifact_downloads/merge_request_artifact_download.vue
+++ b/app/assets/javascripts/vue_shared/security_reports/components/artifact_downloads/merge_request_artifact_download.vue
@@ -1,6 +1,6 @@
<script>
import { reportTypeToSecurityReportTypeEnum } from 'ee_else_ce/vue_shared/security_reports/constants';
-import { createAlert } from '~/flash';
+import { createAlert } from '~/alert';
import { s__ } from '~/locale';
import SecurityReportDownloadDropdown from '~/vue_shared/security_reports/components/security_report_download_dropdown.vue';
import securityReportMergeRequestDownloadPathsQuery from '~/vue_shared/security_reports/graphql/queries/security_report_merge_request_download_paths.query.graphql';
diff --git a/app/assets/javascripts/vue_shared/security_reports/security_reports_app.vue b/app/assets/javascripts/vue_shared/security_reports/security_reports_app.vue
index b739baad5d7..0cff5edf628 100644
--- a/app/assets/javascripts/vue_shared/security_reports/security_reports_app.vue
+++ b/app/assets/javascripts/vue_shared/security_reports/security_reports_app.vue
@@ -1,6 +1,6 @@
<script>
import { mapActions, mapGetters } from 'vuex';
-import { createAlert } from '~/flash';
+import { createAlert } from '~/alert';
import { s__ } from '~/locale';
import ReportSection from '~/ci/reports/components/report_section.vue';
import { ERROR, SLOT_SUCCESS, SLOT_LOADING, SLOT_ERROR } from '~/ci/reports/constants';
diff --git a/app/graphql/mutations/design_management/update.rb b/app/graphql/mutations/design_management/update.rb
new file mode 100644
index 00000000000..5dc20730a90
--- /dev/null
+++ b/app/graphql/mutations/design_management/update.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+
+module Mutations
+ module DesignManagement
+ class Update < ::Mutations::BaseMutation
+ graphql_name "DesignManagementUpdate"
+
+ authorize :update_design
+
+ argument :id, ::Types::GlobalIDType[::DesignManagement::Design],
+ required: true,
+ description: "ID of the design to update."
+
+ argument :description, GraphQL::Types::String,
+ required: false,
+ description: copy_field_description(Types::DesignManagement::DesignType, :description)
+
+ field :design, Types::DesignManagement::DesignType,
+ null: false,
+ description: "Updated design."
+
+ def resolve(id:, description:)
+ design = authorized_find!(id: id)
+ design.update(description: description)
+
+ {
+ design: design.reset,
+ errors: errors_on_object(design)
+ }
+ end
+
+ private
+
+ def find_object(id:)
+ GitlabSchema.find_by_gid(id)
+ end
+ end
+ end
+end
diff --git a/app/graphql/types/design_management/design_type.rb b/app/graphql/types/design_management/design_type.rb
index cc4c0e19ec7..be5edd17643 100644
--- a/app/graphql/types/design_management/design_type.rb
+++ b/app/graphql/types/design_management/design_type.rb
@@ -15,6 +15,11 @@ module Types
implements(Types::CurrentUserTodos)
implements(Types::TodoableInterface)
+ field :description,
+ GraphQL::Types::String,
+ null: true,
+ description: 'Description of the design.'
+
field :web_url,
GraphQL::Types::String,
null: false,
@@ -25,6 +30,8 @@ module Types
resolver: Resolvers::DesignManagement::VersionsResolver,
description: "All versions related to this design ordered newest first."
+ markdown_field :description_html, null: true
+
# Returns a `DesignManagement::Version` for this query based on the
# `atVersion` argument passed to a parent node if present, or otherwise
# the most recent `Version` for the issue.
diff --git a/app/graphql/types/mutation_type.rb b/app/graphql/types/mutation_type.rb
index 108c55f1292..75235405763 100644
--- a/app/graphql/types/mutation_type.rb
+++ b/app/graphql/types/mutation_type.rb
@@ -117,6 +117,7 @@ module Types
mount_mutation Mutations::DesignManagement::Upload, calls_gitaly: true
mount_mutation Mutations::DesignManagement::Delete, calls_gitaly: true
mount_mutation Mutations::DesignManagement::Move
+ mount_mutation Mutations::DesignManagement::Update
mount_mutation Mutations::ContainerExpirationPolicies::Update
mount_mutation Mutations::ContainerRepositories::Destroy
mount_mutation Mutations::ContainerRepositories::DestroyTags
diff --git a/app/policies/issue_policy.rb b/app/policies/issue_policy.rb
index d1e35793c64..804709ed072 100644
--- a/app/policies/issue_policy.rb
+++ b/app/policies/issue_policy.rb
@@ -59,6 +59,7 @@ class IssuePolicy < IssuablePolicy
rule { ~can?(:read_issue) }.policy do
prevent :read_design
prevent :create_design
+ prevent :update_design
prevent :destroy_design
end
diff --git a/app/policies/project_policy.rb b/app/policies/project_policy.rb
index fbe0f9bfeea..2bdd8b23c62 100644
--- a/app/policies/project_policy.rb
+++ b/app/policies/project_policy.rb
@@ -464,6 +464,7 @@ class ProjectPolicy < BasePolicy
enable :read_alert_management_alert
enable :update_alert_management_alert
enable :create_design
+ enable :update_design
enable :move_design
enable :destroy_design
enable :read_terraform_state
@@ -750,6 +751,7 @@ class ProjectPolicy < BasePolicy
prevent :read_design
prevent :read_design_activity
prevent :create_design
+ prevent :update_design
prevent :destroy_design
prevent :move_design
end
diff --git a/app/services/resource_access_tokens/create_service.rb b/app/services/resource_access_tokens/create_service.rb
index 396d6a19dea..8bddf154017 100644
--- a/app/services/resource_access_tokens/create_service.rb
+++ b/app/services/resource_access_tokens/create_service.rb
@@ -1,9 +1,9 @@
# frozen_string_literal: true
-require 'securerandom'
-
module ResourceAccessTokens
class CreateService < BaseService
+ include Gitlab::Utils::StrongMemoize
+
def initialize(current_user, resource, params = {})
@resource_type = resource.class.name.downcase
@resource = resource
@@ -45,6 +45,14 @@ module ResourceAccessTokens
attr_reader :resource_type, :resource
+ def username_and_email_generator
+ Gitlab::Utils::UsernameAndEmailGenerator.new(
+ username_prefix: "#{resource_type}_#{resource.id}_bot",
+ email_domain: "noreply.#{Gitlab.config.gitlab.host}"
+ )
+ end
+ strong_memoize_attr :username_and_email_generator
+
def has_permission_to_create?
%w(project group).include?(resource_type) && can?(current_user, :create_resource_access_tokens, resource)
end
@@ -65,25 +73,13 @@ module ResourceAccessTokens
def default_user_params
{
name: params[:name] || "#{resource.name.to_s.humanize} bot",
- email: generate_email,
- username: generate_username,
+ email: username_and_email_generator.email,
+ username: username_and_email_generator.username,
user_type: :project_bot,
skip_confirmation: true # Bot users should always have their emails confirmed.
}
end
- def generate_username
- username
- end
-
- def generate_email
- "#{username}@noreply.#{Gitlab.config.gitlab.host}"
- end
-
- def username
- @username ||= "#{resource_type}_#{resource.id}_bot_#{SecureRandom.hex(8)}"
- end
-
def create_personal_access_token(user)
PersonalAccessTokens::CreateService.new(
current_user: user, target_user: user, params: personal_access_token_params
diff --git a/app/views/groups/new.html.haml b/app/views/groups/new.html.haml
index 0878fbf9a35..a5cbc443fa4 100644
--- a/app/views/groups/new.html.haml
+++ b/app/views/groups/new.html.haml
@@ -6,7 +6,7 @@
.group-edit-container
- .js-new-group-creation{ data: { has_errors: @group.errors.any?.to_s }.merge(subgroup_creation_data(@group),
+ .js-new-group-creation{ data: { has_errors: @group.errors.any?.to_s, groups_url: dashboard_groups_url }.merge(subgroup_creation_data(@group),
verification_for_group_creation_data) }
.row{ 'v-cloak': true }
diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml
index b493a8d0ce8..f4a5862b2c0 100644
--- a/app/views/projects/new.html.haml
+++ b/app/views/projects/new.html.haml
@@ -8,7 +8,15 @@
.project-edit-errors
= render 'projects/errors'
- .js-new-project-creation{ data: { is_ci_cd_available: remote_mirror_setting_enabled?.to_s, has_errors: @project.errors.any?.to_s, new_project_guidelines: brand_new_project_guidelines, push_to_create_project_command: push_to_create_project_command, working_with_projects_help_path: help_page_path("user/project/working_with_projects"), parent_group_url: @project.parent && group_url(@project.parent), parent_group_name: @project.parent&.name } }
+ .js-new-project-creation{ data: {
+ is_ci_cd_available: remote_mirror_setting_enabled?.to_s,
+ has_errors: @project.errors.any?.to_s,
+ new_project_guidelines: brand_new_project_guidelines,
+ push_to_create_project_command: push_to_create_project_command,
+ working_with_projects_help_path: help_page_path("user/project/working_with_projects"),
+ parent_group_url: @project.parent && group_url(@project.parent),
+ parent_group_name: @project.parent&.name,
+ projects_url: dashboard_projects_url } }
.row{ 'v-cloak': true }
#blank-project-pane.tab-pane.active