-
- {{ webPath }}
+
+
+
+
+
+
+
+ {{ webPath }}
+
+
+ {{ resource.name }}
+
+ {{ versionBadgeText }}
+
+
+
-
- {{ resource.name }}
-
+
+
+
- {{ versionBadgeText }}
-
-
-
+
+ {{ $options.i18n.reportAbuse }}
+
+
+
{{ resource.description }}
+
diff --git a/app/assets/javascripts/ci/catalog/graphql/fragments/catalog_resource.fragment.graphql b/app/assets/javascripts/ci/catalog/graphql/fragments/catalog_resource.fragment.graphql
index db706006688..ded14b18664 100644
--- a/app/assets/javascripts/ci/catalog/graphql/fragments/catalog_resource.fragment.graphql
+++ b/app/assets/javascripts/ci/catalog/graphql/fragments/catalog_resource.fragment.graphql
@@ -21,6 +21,7 @@ fragment CatalogResourceFields on CiCatalogResource {
author {
id
name
+ state
webUrl
}
}
diff --git a/app/assets/javascripts/ci/catalog/index.js b/app/assets/javascripts/ci/catalog/index.js
index 34866bfb821..0678f7f2126 100644
--- a/app/assets/javascripts/ci/catalog/index.js
+++ b/app/assets/javascripts/ci/catalog/index.js
@@ -15,7 +15,7 @@ export const initCatalog = (selector = '#js-ci-cd-catalog') => {
}
const { dataset } = el;
- const { ciCatalogPath } = dataset;
+ const { ciCatalogPath, reportAbusePath } = dataset;
Vue.use(VueApollo);
@@ -30,6 +30,7 @@ export const initCatalog = (selector = '#js-ci-cd-catalog') => {
apolloProvider,
provide: {
ciCatalogPath,
+ reportAbusePath,
},
render(h) {
return h(GlobalCatalog);
diff --git a/app/assets/javascripts/content_editor/components/formatting_toolbar.vue b/app/assets/javascripts/content_editor/components/formatting_toolbar.vue
index c1eae345f72..5eea12de477 100644
--- a/app/assets/javascripts/content_editor/components/formatting_toolbar.vue
+++ b/app/assets/javascripts/content_editor/components/formatting_toolbar.vue
@@ -21,7 +21,7 @@ export default {
HeaderDivider,
},
inject: {
- newCommentTemplatePath: { default: null },
+ newCommentTemplatePaths: { default: () => [] },
tiptapEditor: { default: null },
contentEditor: { default: null },
},
@@ -199,11 +199,11 @@ export default {
:label="__('Add a quick action')"
@execute="trackToolbarControlExecution"
/>
-
+
diff --git a/app/assets/javascripts/design_management/index.js b/app/assets/javascripts/design_management/index.js
index 12bb4b830f8..e4d3f1a3341 100644
--- a/app/assets/javascripts/design_management/index.js
+++ b/app/assets/javascripts/design_management/index.js
@@ -14,7 +14,7 @@ export default () => {
issuePath,
registerPath,
signInPath,
- newCommentTemplatePath,
+ newCommentTemplatePaths,
} = el.dataset;
const router = createRouter(issuePath);
@@ -39,7 +39,7 @@ export default () => {
issueIid,
registerPath,
signInPath,
- newCommentTemplatePath,
+ newCommentTemplatePaths: JSON.parse(newCommentTemplatePaths),
},
mounted() {
performanceMarkAndMeasure({
diff --git a/app/assets/javascripts/diffs/index.js b/app/assets/javascripts/diffs/index.js
index 9acfda93303..eed57d2edd5 100644
--- a/app/assets/javascripts/diffs/index.js
+++ b/app/assets/javascripts/diffs/index.js
@@ -17,6 +17,7 @@ export default function initDiffsApp(store = notesStore) {
const { dataset } = el;
Vue.use(VueApollo);
+ const { newCommentTemplatePaths } = dataset;
const vm = new Vue({
el,
@@ -27,7 +28,7 @@ export default function initDiffsApp(store = notesStore) {
store,
apolloProvider,
provide: {
- newCommentTemplatePath: dataset.newCommentTemplatePath,
+ newCommentTemplatePaths: newCommentTemplatePaths ? JSON.parse(newCommentTemplatePaths) : [],
},
data() {
return {
diff --git a/app/assets/javascripts/filtered_search/issuable_filtered_search_token_keys.js b/app/assets/javascripts/filtered_search/issuable_filtered_search_token_keys.js
index 5a785de2e66..7665b53013b 100644
--- a/app/assets/javascripts/filtered_search/issuable_filtered_search_token_keys.js
+++ b/app/assets/javascripts/filtered_search/issuable_filtered_search_token_keys.js
@@ -43,7 +43,7 @@ export const createTokenKeys = ({ disableReleaseFilter = false } = {}) => {
type: 'string',
param: 'title',
symbol: '%',
- icon: 'clock',
+ icon: 'milestone',
tag: '%milestone',
},
{
diff --git a/app/assets/javascripts/issuable/components/issuable_by_email.vue b/app/assets/javascripts/issuable/components/issuable_by_email.vue
index 71ec5544c34..647339d3dc2 100644
--- a/app/assets/javascripts/issuable/components/issuable_by_email.vue
+++ b/app/assets/javascripts/issuable/components/issuable_by_email.vue
@@ -52,6 +52,23 @@ export default {
default: '',
},
},
+ props: {
+ buttonClass: {
+ type: String,
+ required: false,
+ default: null,
+ },
+ variant: {
+ type: String,
+ required: false,
+ default: 'link',
+ },
+ text: {
+ type: String,
+ required: false,
+ default: __('Email a new %{name} to this project'),
+ },
+ },
data() {
return {
email: this.initialEmail,
@@ -90,8 +107,8 @@ export default {
-
{{ issuableName }}
diff --git a/app/assets/javascripts/issuable/components/issue_milestone.vue b/app/assets/javascripts/issuable/components/issue_milestone.vue
index 3340ef2338c..5f40d2f5935 100644
--- a/app/assets/javascripts/issuable/components/issue_milestone.vue
+++ b/app/assets/javascripts/issuable/components/issue_milestone.vue
@@ -73,7 +73,7 @@ export default {
-
+
{{
milestone.title
}}
diff --git a/app/assets/javascripts/issues/dashboard/components/issues_dashboard_app.vue b/app/assets/javascripts/issues/dashboard/components/issues_dashboard_app.vue
index 2353aceb5ae..5bce755105b 100644
--- a/app/assets/javascripts/issues/dashboard/components/issues_dashboard_app.vue
+++ b/app/assets/javascripts/issues/dashboard/components/issues_dashboard_app.vue
@@ -258,7 +258,7 @@ export default {
{
type: TOKEN_TYPE_MILESTONE,
title: TOKEN_TITLE_MILESTONE,
- icon: 'clock',
+ icon: 'milestone',
token: MilestoneToken,
fetchMilestones: this.fetchMilestones,
recentSuggestionsStorageKey: 'dashboard-issues-recent-tokens-milestone',
diff --git a/app/assets/javascripts/issues/list/components/empty_state_without_any_issues.vue b/app/assets/javascripts/issues/list/components/empty_state_without_any_issues.vue
index 6741b39d5ef..382bb845311 100644
--- a/app/assets/javascripts/issues/list/components/empty_state_without_any_issues.vue
+++ b/app/assets/javascripts/issues/list/components/empty_state_without_any_issues.vue
@@ -3,8 +3,10 @@ import { GlButton, GlDisclosureDropdown, GlEmptyState, GlLink, GlSprintf } from
import { helpPagePath } from '~/helpers/help_page_helper';
import CsvImportExportButtons from '~/issuable/components/csv_import_export_buttons.vue';
import NewResourceDropdown from '~/vue_shared/components/new_resource_dropdown/new_resource_dropdown.vue';
+import GitlabExperiment from '~/experimentation/components/gitlab_experiment.vue';
import { i18n } from '../constants';
import { hasNewIssueDropdown } from '../has_new_issue_dropdown_mixin';
+import EmptyStateWithoutAnyIssuesExperiment from './empty_state_without_any_issues_experiment.vue';
export default {
i18n,
@@ -17,6 +19,8 @@ export default {
GlLink,
GlSprintf,
NewResourceDropdown,
+ GitlabExperiment,
+ EmptyStateWithoutAnyIssuesExperiment,
},
mixins: [hasNewIssueDropdown()],
inject: [
@@ -51,80 +55,102 @@ export default {
required: false,
default: false,
},
+ showIssuableByEmail: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
},
};
-
-
-
- {{ $options.i18n.noIssuesDescription }}
-
-
- {{ $options.i18n.noGroupIssuesSignedInDescription }}
-
-
-
-
- {{ $options.i18n.newProjectLabel }}
-
-
- {{ $options.i18n.newIssueLabel }}
-
-
-
-
-
-
-
+
+
-
-
-
- {{ $options.i18n.jiraIntegrationTitle }}
-
-
-
-
- {{ content }}
-
-
-
-
- {{ $options.i18n.jiraIntegrationSecondaryMessage }}
-
+
+
+
+
+
+
+ {{ $options.i18n.noIssuesDescription }}
+
+
+ {{ $options.i18n.noGroupIssuesSignedInDescription }}
+
+
+
+
+
+ {{ $options.i18n.newProjectLabel }}
+
+
+ {{ $options.i18n.newIssueLabel }}
+
+
+
+
+
+
+
+
+
+
+
+ {{ $options.i18n.jiraIntegrationTitle }}
+
+
+
+
+ {{ content }}
+
+
+
+
+ {{ $options.i18n.jiraIntegrationSecondaryMessage }}
+
+
+
+
+import { GlButton, GlModalDirective, GlIcon } from '@gitlab/ui';
+import { TYPE_ISSUE } from '~/issues/constants';
+import { helpPagePath } from '~/helpers/help_page_helper';
+import IssuableByEmail from '~/issuable/components/issuable_by_email.vue';
+import CsvImportModal from '~/issuable/components/csv_import_modal.vue';
+import { i18n } from '../constants';
+import GlCardEmptyStateExperiment from './gl_card_empty_state_experiment.vue';
+
+export default {
+ i18n,
+ issuesHelpPagePath: helpPagePath('user/project/issues/index'),
+ components: {
+ GlCardEmptyStateExperiment,
+ GlButton,
+ GlIcon,
+ IssuableByEmail,
+ CsvImportModal,
+ },
+ directives: {
+ GlModal: GlModalDirective,
+ },
+ inject: {
+ jiraIntegrationPath: {
+ default: null,
+ },
+ newIssuePath: {
+ default: null,
+ },
+ showNewIssueLink: {
+ default: false,
+ },
+ showImportButton: {
+ default: false,
+ },
+ canEdit: {
+ default: false,
+ },
+ projectImportJiraPath: {
+ default: null,
+ },
+ },
+ props: {
+ showCsvButtons: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ showIssuableByEmail: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ },
+ computed: {
+ importModalId() {
+ return `${TYPE_ISSUE}-import-modal`;
+ },
+ },
+};
+
+
+
+
+
+
+
+ {{ $options.i18n.noIssuesTitle }}
+
+
+
+ {{
+ __(
+ 'With issues you can discuss the implementation of an idea, track tasks and work status, elaborate on code implementations, and accept feature proposals, questions, support requests, or bug reports.',
+ )
+ }}
+
+
+
+
+ {{ __('Create a new issue') }}
+
+
+
+
+
+
+
+
diff --git a/app/assets/javascripts/issues/list/components/gl_card_empty_state_experiment.vue b/app/assets/javascripts/issues/list/components/gl_card_empty_state_experiment.vue
new file mode 100644
index 00000000000..341a5f38a8e
--- /dev/null
+++ b/app/assets/javascripts/issues/list/components/gl_card_empty_state_experiment.vue
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
diff --git a/app/assets/javascripts/issues/list/components/issue_card_time_info.vue b/app/assets/javascripts/issues/list/components/issue_card_time_info.vue
index 22c0984ebdb..a263017fed4 100644
--- a/app/assets/javascripts/issues/list/components/issue_card_time_info.vue
+++ b/app/assets/javascripts/issues/list/components/issue_card_time_info.vue
@@ -95,7 +95,7 @@ export default {
:title="milestoneDate"
class="gl-font-sm gl-text-gray-500!"
>
-
+
{{ milestone.title }}
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 3469dfdc804..a87b6b65416 100644
--- a/app/assets/javascripts/issues/list/components/issues_list_app.vue
+++ b/app/assets/javascripts/issues/list/components/issues_list_app.vue
@@ -75,6 +75,7 @@ import NewResourceDropdown from '~/vue_shared/components/new_resource_dropdown/n
import WorkItemDetail from '~/work_items/components/work_item_detail.vue';
import deleteWorkItemMutation from '~/work_items/graphql/delete_work_item.mutation.graphql';
import { WORK_ITEM_TYPE_ENUM_OBJECTIVE } from '~/work_items/constants';
+import GitlabExperiment from '~/experimentation/components/gitlab_experiment.vue';
import {
CREATED_DESC,
defaultTypeTokenOptions,
@@ -153,6 +154,7 @@ export default {
LocalStorageSync,
WorkItemDetail,
GlLink,
+ GitlabExperiment,
},
directives: {
GlTooltip: GlTooltipDirective,
@@ -403,7 +405,7 @@ export default {
{
type: TOKEN_TYPE_MILESTONE,
title: TOKEN_TITLE_MILESTONE,
- icon: 'clock',
+ icon: 'milestone',
token: MilestoneToken,
recentSuggestionsStorageKey: `${this.fullPath}-issues-recent-tokens-milestone`,
shouldSkipSort: true,
@@ -1073,8 +1075,13 @@ export default {
:export-csv-path-with-query="exportCsvPathWithQuery"
:show-csv-buttons="showCsvButtons"
:show-new-issue-dropdown="showNewIssueDropdown"
+ :show-issuable-by-email="showIssuableByEmail"
/>
-
+
+
+
+
+
diff --git a/app/assets/javascripts/issues/service_desk/search_tokens.js b/app/assets/javascripts/issues/service_desk/search_tokens.js
index 72750f518e4..d72ecc78c22 100644
--- a/app/assets/javascripts/issues/service_desk/search_tokens.js
+++ b/app/assets/javascripts/issues/service_desk/search_tokens.js
@@ -56,7 +56,7 @@ export const assigneeTokenBase = {
export const milestoneTokenBase = {
type: TOKEN_TYPE_MILESTONE,
title: TOKEN_TITLE_MILESTONE,
- icon: 'clock',
+ icon: 'milestone',
token: MilestoneToken,
shouldSkipSort: true,
};
diff --git a/app/assets/javascripts/mr_notes/init_notes.js b/app/assets/javascripts/mr_notes/init_notes.js
index 265e2a2f880..f3e12e0672b 100644
--- a/app/assets/javascripts/mr_notes/init_notes.js
+++ b/app/assets/javascripts/mr_notes/init_notes.js
@@ -42,7 +42,7 @@ export default () => {
apolloProvider,
provide: {
reportAbusePath: notesDataset.reportAbusePath,
- newCommentTemplatePath: notesDataset.newCommentTemplatePath,
+ newCommentTemplatePaths: JSON.parse(notesDataset.newCommentTemplatePaths),
mrFilter: true,
newCustomEmojiPath: notesDataset.newCustomEmojiPath,
},
diff --git a/app/assets/javascripts/notes/index.js b/app/assets/javascripts/notes/index.js
index f9fbe6659ee..0931d404be0 100644
--- a/app/assets/javascripts/notes/index.js
+++ b/app/assets/javascripts/notes/index.js
@@ -59,7 +59,7 @@ export default ({ editorAiActions = [] } = {}) => {
provide: {
showTimelineViewToggle,
reportAbusePath: notesDataset.reportAbusePath,
- newCommentTemplatePath: notesDataset.newCommentTemplatePath,
+ newCommentTemplatePaths: JSON.parse(notesDataset.newCommentTemplatePaths),
resourceGlobalId: convertToGraphQLId(noteableData.noteableType, noteableData.id),
editorAiActions: editorAiActions.map((factory) => factory(noteableData)),
newCustomEmojiPath: notesDataset.newCustomEmojiPath,
diff --git a/app/assets/javascripts/search/store/constants.js b/app/assets/javascripts/search/store/constants.js
index 1d6720b5936..3ae8366d129 100644
--- a/app/assets/javascripts/search/store/constants.js
+++ b/app/assets/javascripts/search/store/constants.js
@@ -29,7 +29,7 @@ export const ICON_MAP = {
merge_requests: 'merge-request',
commits: 'commit',
notes: 'comments',
- milestones: 'clock',
+ milestones: 'milestone',
users: 'users',
projects: 'project',
wiki_blobs: 'book',
diff --git a/app/assets/javascripts/sidebar/mount_sidebar.js b/app/assets/javascripts/sidebar/mount_sidebar.js
index fe9f15414cf..c7af7398eff 100644
--- a/app/assets/javascripts/sidebar/mount_sidebar.js
+++ b/app/assets/javascripts/sidebar/mount_sidebar.js
@@ -272,7 +272,7 @@ function mountSidebarMilestoneWidget() {
iid: issueIid,
issuableType: isInIssuePage() || isInDesignPage() ? TYPE_ISSUE : TYPE_MERGE_REQUEST,
issuableAttribute: IssuableAttributeType.Milestone,
- icon: 'clock',
+ icon: 'milestone',
},
}),
});
diff --git a/app/assets/javascripts/vue_shared/components/markdown/comment_templates_dropdown.vue b/app/assets/javascripts/vue_shared/components/markdown/comment_templates_dropdown.vue
index de6237c2d6b..7bf433795a5 100644
--- a/app/assets/javascripts/vue_shared/components/markdown/comment_templates_dropdown.vue
+++ b/app/assets/javascripts/vue_shared/components/markdown/comment_templates_dropdown.vue
@@ -42,8 +42,8 @@ export default {
},
mixins: [InternalEvents.mixin()],
props: {
- newCommentTemplatePath: {
- type: String,
+ newCommentTemplatePaths: {
+ type: Array,
required: true,
},
},
@@ -147,14 +147,17 @@ export default {
{{ __('Add a new comment template') }}{{ manage.text }}
@@ -167,7 +170,7 @@ export default {