Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts')
-rw-r--r--app/assets/javascripts/batch_comments/stores/modules/batch_comments/actions.js18
-rw-r--r--app/assets/javascripts/ci/pipeline_details/graph/components/graph_component.vue1
-rw-r--r--app/assets/javascripts/ci/pipeline_details/graph/components/linked_graph_wrapper.vue5
-rw-r--r--app/assets/javascripts/ci/pipeline_details/graph/components/linked_pipelines_column.vue2
-rw-r--r--app/assets/javascripts/ci/pipeline_details/graph/components/stage_column_component.vue2
-rw-r--r--app/assets/javascripts/ci/pipeline_details/header/pipeline_details_header.vue7
-rw-r--r--app/assets/javascripts/diffs/components/app.vue21
-rw-r--r--app/assets/javascripts/diffs/components/diff_discussions.vue7
-rw-r--r--app/assets/javascripts/diffs/store/actions.js6
-rw-r--r--app/assets/javascripts/diffs/store/mutations.js5
-rw-r--r--app/assets/javascripts/diffs/store/utils.js2
-rw-r--r--app/assets/javascripts/environments/components/environments_app.vue8
-rw-r--r--app/assets/javascripts/issuable/components/related_issuable_item.vue4
-rw-r--r--app/assets/javascripts/issuable/components/status_badge.vue10
-rw-r--r--app/assets/javascripts/issues/show/components/issue_header.vue2
-rw-r--r--app/assets/javascripts/issues/show/components/sticky_header.vue12
-rw-r--r--app/assets/javascripts/lib/utils/color_utils.js2
-rw-r--r--app/assets/javascripts/notes/components/noteable_discussion.vue4
-rw-r--r--app/assets/javascripts/notes/stores/mutations.js5
-rw-r--r--app/assets/javascripts/observability/client.js28
-rw-r--r--app/assets/javascripts/organizations/users/graphql/organization_users.query.graphql5
-rw-r--r--app/assets/javascripts/persistent_user_callouts.js1
-rw-r--r--app/assets/javascripts/profile/preferences/components/profile_preferences.vue6
-rw-r--r--app/assets/javascripts/projects/settings/init_access_dropdown.js1
-rw-r--r--app/assets/javascripts/protected_branches/protected_branch_edit.js14
-rw-r--r--app/assets/javascripts/super_sidebar/components/user_menu.vue11
-rw-r--r--app/assets/javascripts/super_sidebar/super_sidebar_bundle.js9
-rw-r--r--app/assets/javascripts/vue_shared/components/diff_stats_dropdown.vue122
-rw-r--r--app/assets/javascripts/vue_shared/components/list_selector/constants.js2
-rw-r--r--app/assets/javascripts/vue_shared/components/list_selector/index.vue128
-rw-r--r--app/assets/javascripts/vue_shared/issuable/show/components/issuable_body.vue6
-rw-r--r--app/assets/javascripts/vue_shared/issuable/show/components/issuable_show_root.vue1
-rw-r--r--app/assets/javascripts/vue_shared/issuable/show/components/issuable_title.vue13
-rw-r--r--app/assets/javascripts/work_items/components/work_item_type_icon.vue5
-rw-r--r--app/assets/javascripts/work_items/constants.js6
35 files changed, 256 insertions, 225 deletions
diff --git a/app/assets/javascripts/batch_comments/stores/modules/batch_comments/actions.js b/app/assets/javascripts/batch_comments/stores/modules/batch_comments/actions.js
index 070ce38c8aa..d97f11a0acd 100644
--- a/app/assets/javascripts/batch_comments/stores/modules/batch_comments/actions.js
+++ b/app/assets/javascripts/batch_comments/stores/modules/batch_comments/actions.js
@@ -72,22 +72,20 @@ export const fetchDrafts = ({ commit, getters, state, dispatch }) =>
}),
);
-export const publishSingleDraft = ({ commit, dispatch, getters }, draftId) => {
+export const publishSingleDraft = ({ commit, getters }, draftId) => {
commit(types.REQUEST_PUBLISH_DRAFT, draftId);
service
.publishDraft(getters.getNotesData.draftsPublishPath, draftId)
- .then(() => dispatch('updateDiscussionsAfterPublish'))
.then(() => commit(types.RECEIVE_PUBLISH_DRAFT_SUCCESS, draftId))
.catch(() => commit(types.RECEIVE_PUBLISH_DRAFT_ERROR, draftId));
};
-export const publishReview = ({ commit, dispatch, getters }, noteData = {}) => {
+export const publishReview = ({ commit, getters }, noteData = {}) => {
commit(types.REQUEST_PUBLISH_REVIEW);
return service
.publish(getters.getNotesData.draftsPublishPath, noteData)
- .then(() => dispatch('updateDiscussionsAfterPublish'))
.then(() => commit(types.RECEIVE_PUBLISH_REVIEW_SUCCESS))
.catch((e) => {
commit(types.RECEIVE_PUBLISH_REVIEW_ERROR);
@@ -96,18 +94,6 @@ export const publishReview = ({ commit, dispatch, getters }, noteData = {}) => {
});
};
-export const updateDiscussionsAfterPublish = async ({ dispatch, getters, rootGetters }) => {
- await dispatch(
- 'fetchDiscussions',
- { path: getters.getNotesData.discussionsPath },
- { root: true },
- );
-
- dispatch('diffs/assignDiscussionsToDiff', rootGetters.discussionsStructuredByLineCode, {
- root: true,
- });
-};
-
export const updateDraft = (
{ commit, getters },
{ note, noteText, resolveDiscussion, position, flashContainer, callback, errorCallback },
diff --git a/app/assets/javascripts/ci/pipeline_details/graph/components/graph_component.vue b/app/assets/javascripts/ci/pipeline_details/graph/components/graph_component.vue
index fce7aabf0cf..3da2f27c1b9 100644
--- a/app/assets/javascripts/ci/pipeline_details/graph/components/graph_component.vue
+++ b/app/assets/javascripts/ci/pipeline_details/graph/components/graph_component.vue
@@ -248,7 +248,6 @@ export default {
<template #downstream>
<linked-pipelines-column
v-if="showDownstreamPipelines"
- class="gl-mr-5"
:class="{ 'gl-sm-ml-3': isNewPipelineGraph }"
:config-paths="configPaths"
:linked-pipelines="downstreamPipelines"
diff --git a/app/assets/javascripts/ci/pipeline_details/graph/components/linked_graph_wrapper.vue b/app/assets/javascripts/ci/pipeline_details/graph/components/linked_graph_wrapper.vue
index 9bd0ec6d793..0d72373a0f5 100644
--- a/app/assets/javascripts/ci/pipeline_details/graph/components/linked_graph_wrapper.vue
+++ b/app/assets/javascripts/ci/pipeline_details/graph/components/linked_graph_wrapper.vue
@@ -11,7 +11,10 @@ export default {
};
</script>
<template>
- <div class="gl-display-flex" :class="{ 'gl-flex-wrap gl-w-full': isNewPipelineGraph }">
+ <div
+ class="gl-display-flex"
+ :class="{ 'gl-flex-wrap gl-sm-flex-nowrap gl-w-full': isNewPipelineGraph }"
+ >
<slot name="upstream"></slot>
<slot name="main"></slot>
<slot name="downstream"></slot>
diff --git a/app/assets/javascripts/ci/pipeline_details/graph/components/linked_pipelines_column.vue b/app/assets/javascripts/ci/pipeline_details/graph/components/linked_pipelines_column.vue
index 67918ea8d1a..c715d6af28a 100644
--- a/app/assets/javascripts/ci/pipeline_details/graph/components/linked_pipelines_column.vue
+++ b/app/assets/javascripts/ci/pipeline_details/graph/components/linked_pipelines_column.vue
@@ -74,7 +74,7 @@ export default {
left: 'gl-mx-6',
};
const positionValues = {
- right: 'gl-ml-5',
+ right: 'gl-mx-5',
left: 'gl-mx-4 gl-flex-basis-full',
};
const usePositionValues = this.isNewPipelineGraph ? positionValues : positionValuesOld;
diff --git a/app/assets/javascripts/ci/pipeline_details/graph/components/stage_column_component.vue b/app/assets/javascripts/ci/pipeline_details/graph/components/stage_column_component.vue
index e144b9aab0c..01a9c6d030d 100644
--- a/app/assets/javascripts/ci/pipeline_details/graph/components/stage_column_component.vue
+++ b/app/assets/javascripts/ci/pipeline_details/graph/components/stage_column_component.vue
@@ -179,7 +179,7 @@ export default {
<template #stages>
<div
data-testid="stage-column-title"
- class="gl-display-flex gl-justify-content-space-between gl-relative"
+ class="stage-column-title gl-display-flex gl-justify-content-space-between gl-relative"
:class="titleClasses"
>
<span :title="name" class="gl-text-truncate gl-pr-3 gl-w-85p">
diff --git a/app/assets/javascripts/ci/pipeline_details/header/pipeline_details_header.vue b/app/assets/javascripts/ci/pipeline_details/header/pipeline_details_header.vue
index 5c1841615ab..dc4a2d91c84 100644
--- a/app/assets/javascripts/ci/pipeline_details/header/pipeline_details_header.vue
+++ b/app/assets/javascripts/ci/pipeline_details/header/pipeline_details_header.vue
@@ -403,12 +403,7 @@ export default {
{{ commitTitle }}
</h3>
<div>
- <ci-icon
- :status="detailedStatus"
- show-status-text
- :show-link="false"
- class="gl-display-inline-block gl-mb-3"
- />
+ <ci-icon :status="detailedStatus" show-status-text :show-link="false" class="gl-mb-3" />
<div class="gl-ml-2 gl-mb-3 gl-display-inline-block gl-h-6">
<gl-link
v-if="user"
diff --git a/app/assets/javascripts/diffs/components/app.vue b/app/assets/javascripts/diffs/components/app.vue
index 7c3d6dc8c42..9971d3bf7f8 100644
--- a/app/assets/javascripts/diffs/components/app.vue
+++ b/app/assets/javascripts/diffs/components/app.vue
@@ -366,22 +366,11 @@ export default {
handleLocationHash();
this.autoScrolled = true;
}, DEFAULT_DEBOUNCE_AND_THROTTLE_MS);
- this.unwatchDiscussions = this.$watch(
- () => `${this.flatBlobsList.length}:${this.$store.state.notes.discussions.length}`,
- () => {
- this.setDiscussions();
-
- if (this.$store.state.notes.doneFetchingBatchDiscussions) {
- this.unwatchDiscussions();
- }
- },
- );
-
- this.unwatchRetrievingBatches = this.$watch(
- () => `${this.retrievingBatches}:${this.$store.state.notes.discussions.length}`,
- () => {
- if (!this.retrievingBatches && this.$store.state.notes.discussions.length) {
- this.unwatchRetrievingBatches();
+ this.$watch(
+ () => this.$store.state.notes.discussions.length,
+ (newVal, prevVal) => {
+ if (newVal > prevVal) {
+ this.setDiscussions();
}
},
);
diff --git a/app/assets/javascripts/diffs/components/diff_discussions.vue b/app/assets/javascripts/diffs/components/diff_discussions.vue
index 8915f32eadf..556f72059c2 100644
--- a/app/assets/javascripts/diffs/components/diff_discussions.vue
+++ b/app/assets/javascripts/diffs/components/diff_discussions.vue
@@ -39,12 +39,6 @@ export default {
},
methods: {
...mapActions(['toggleDiscussion']),
- ...mapActions('diffs', ['removeDiscussionsFromDiff']),
- deleteNoteHandler(discussion) {
- if (discussion.notes.length <= 1) {
- this.removeDiscussionsFromDiff(discussion);
- }
- },
isExpanded(discussion) {
return this.shouldCollapseDiscussions ? discussion.expanded : true;
},
@@ -90,7 +84,6 @@ export default {
:line="line"
:help-page-path="helpPagePath"
:should-scroll-to-note="false"
- @noteDeleted="deleteNoteHandler"
>
<template v-if="renderAvatarBadge" #avatar-badge>
<design-note-pin
diff --git a/app/assets/javascripts/diffs/store/actions.js b/app/assets/javascripts/diffs/store/actions.js
index d86a88f97b8..756f76569dc 100644
--- a/app/assets/javascripts/diffs/store/actions.js
+++ b/app/assets/javascripts/diffs/store/actions.js
@@ -419,7 +419,11 @@ export const assignDiscussionsToDiff = (
};
export const removeDiscussionsFromDiff = ({ commit }, removeDiscussion) => {
- const { file_hash: fileHash, line_code: lineCode, id } = removeDiscussion;
+ const {
+ diff_file: { file_hash: fileHash },
+ line_code: lineCode,
+ id,
+ } = removeDiscussion;
commit(types.REMOVE_LINE_DISCUSSIONS_FOR_FILE, { fileHash, lineCode, id });
};
diff --git a/app/assets/javascripts/diffs/store/mutations.js b/app/assets/javascripts/diffs/store/mutations.js
index 31369b169f5..a9a2c35faa4 100644
--- a/app/assets/javascripts/diffs/store/mutations.js
+++ b/app/assets/javascripts/diffs/store/mutations.js
@@ -198,9 +198,10 @@ export default {
return {
...line,
discussionsExpanded:
- line.discussions && line.discussions.length
+ line.discussionsExpanded ||
+ (line.discussions && line.discussions.length
? line.discussions.some((disc) => !disc.resolved) || isLineNoteTargeted
- : false,
+ : false),
};
};
diff --git a/app/assets/javascripts/diffs/store/utils.js b/app/assets/javascripts/diffs/store/utils.js
index 15d2ab71bc8..fb467a606b9 100644
--- a/app/assets/javascripts/diffs/store/utils.js
+++ b/app/assets/javascripts/diffs/store/utils.js
@@ -338,7 +338,7 @@ function prepareLine(line, file) {
problems.brokenSymlink || problems.fileOnlyMoved || problems.brokenLineCode,
),
rich_text: cleanRichText(line.rich_text),
- discussionsExpanded: true,
+ discussionsExpanded: false,
discussions: [],
hasForm: false,
text: undefined,
diff --git a/app/assets/javascripts/environments/components/environments_app.vue b/app/assets/javascripts/environments/components/environments_app.vue
index 795cbf5327a..fd5fcb12cc5 100644
--- a/app/assets/javascripts/environments/components/environments_app.vue
+++ b/app/assets/javascripts/environments/components/environments_app.vue
@@ -112,6 +112,9 @@ export default {
canSetupReviewApp() {
return this.environmentApp?.reviewApp?.canSetupReviewApp;
},
+ hasReviewApp() {
+ return this.environmentApp?.reviewApp?.hasReviewApp;
+ },
canCleanUpEnvs() {
return this.environmentApp?.canStopStaleEnvironments;
},
@@ -157,7 +160,10 @@ export default {
};
},
openReviewAppModal() {
- if (!this.canSetupReviewApp) {
+ // we don't show the Enable review apps button
+ // if a user cannot setup a review app or review
+ // apps are already configured
+ if (!this.canSetupReviewApp || this.hasReviewApp) {
return null;
}
diff --git a/app/assets/javascripts/issuable/components/related_issuable_item.vue b/app/assets/javascripts/issuable/components/related_issuable_item.vue
index 2ee7b604253..126a3a84d66 100644
--- a/app/assets/javascripts/issuable/components/related_issuable_item.vue
+++ b/app/assets/javascripts/issuable/components/related_issuable_item.vue
@@ -194,7 +194,7 @@ export default {
<div
class="item-attributes-area gl-display-flex gl-align-items-center gl-flex-wrap gl-gap-3"
>
- <span v-if="hasPipeline" class="mr-ci-status order-md-last">
+ <span v-if="hasPipeline" class="mr-ci-status order-md-last gl-md-ml-3 gl-mr-n2">
<a :href="pipelinePath">
<ci-icon :status="pipelineStatus" :title="pipelineStatusTooltip" />
</a>
@@ -203,7 +203,7 @@ export default {
<issue-milestone
v-if="hasMilestone"
:milestone="milestone"
- class="item-milestone gl-font-sm gl-display-flex gl-align-items-center order-md-first"
+ class="item-milestone gl-font-sm gl-display-flex gl-align-items-center order-md-first gl-ml-2"
/>
<!-- Flex order for slots is defined in the parent component: e.g. related_issues_block.vue -->
diff --git a/app/assets/javascripts/issuable/components/status_badge.vue b/app/assets/javascripts/issuable/components/status_badge.vue
index 949fb3c1ce5..35f6446d582 100644
--- a/app/assets/javascripts/issuable/components/status_badge.vue
+++ b/app/assets/javascripts/issuable/components/status_badge.vue
@@ -14,29 +14,29 @@ import {
const badgePropertiesMap = {
[TYPE_EPIC]: {
[STATUS_OPEN]: {
- icon: 'epic',
+ icon: 'issue-open-m',
text: __('Open'),
variant: 'success',
},
[STATUS_CLOSED]: {
- icon: 'epic-closed',
+ icon: 'issue-close',
text: __('Closed'),
variant: 'info',
},
},
[TYPE_ISSUE]: {
[STATUS_OPEN]: {
- icon: 'issues',
+ icon: 'issue-open-m',
text: __('Open'),
variant: 'success',
},
[STATUS_CLOSED]: {
- icon: 'issue-closed',
+ icon: 'issue-close',
text: __('Closed'),
variant: 'info',
},
[STATUS_LOCKED]: {
- icon: 'issues',
+ icon: 'issue-open-m',
text: __('Open'),
variant: 'success',
},
diff --git a/app/assets/javascripts/issues/show/components/issue_header.vue b/app/assets/javascripts/issues/show/components/issue_header.vue
index c205a6361c7..96eb8fbb3c7 100644
--- a/app/assets/javascripts/issues/show/components/issue_header.vue
+++ b/app/assets/javascripts/issues/show/components/issue_header.vue
@@ -82,7 +82,7 @@ export default {
return this.issuableState === STATUS_OPEN || this.issuableState === STATUS_REOPENED;
},
statusIcon() {
- return this.isOpen ? 'issues' : 'issue-closed';
+ return this.isOpen ? 'issue-open-m' : 'issue-close';
},
statusText() {
if (this.isOpen) {
diff --git a/app/assets/javascripts/issues/show/components/sticky_header.vue b/app/assets/javascripts/issues/show/components/sticky_header.vue
index d75f6c75ba5..18e37c4216c 100644
--- a/app/assets/javascripts/issues/show/components/sticky_header.vue
+++ b/app/assets/javascripts/issues/show/components/sticky_header.vue
@@ -2,12 +2,7 @@
import { GlBadge, GlIcon, GlIntersectionObserver, GlLink } from '@gitlab/ui';
import HiddenBadge from '~/issuable/components/hidden_badge.vue';
import LockedBadge from '~/issuable/components/locked_badge.vue';
-import {
- issuableStatusText,
- STATUS_CLOSED,
- TYPE_EPIC,
- WORKSPACE_PROJECT,
-} from '~/issues/constants';
+import { issuableStatusText, STATUS_CLOSED, WORKSPACE_PROJECT } from '~/issues/constants';
import ConfidentialityBadge from '~/vue_shared/components/confidentiality_badge.vue';
export default {
@@ -60,10 +55,7 @@ export default {
return this.issuableStatus === STATUS_CLOSED;
},
statusIcon() {
- if (this.issuableType === TYPE_EPIC) {
- return this.isClosed ? 'epic-closed' : 'epic';
- }
- return this.isClosed ? 'issue-closed' : 'issues';
+ return this.isClosed ? 'issue-close' : 'issue-open-m';
},
statusText() {
return issuableStatusText[this.issuableStatus];
diff --git a/app/assets/javascripts/lib/utils/color_utils.js b/app/assets/javascripts/lib/utils/color_utils.js
index a9f4257e28b..74c9f7de8c1 100644
--- a/app/assets/javascripts/lib/utils/color_utils.js
+++ b/app/assets/javascripts/lib/utils/color_utils.js
@@ -46,5 +46,5 @@ export function darkModeEnabled() {
if (isWebIde) {
return ideDarkThemes.includes(window.gon?.user_color_scheme);
}
- return document.body.classList.contains('gl-dark');
+ return document.documentElement.classList.contains('gl-dark');
}
diff --git a/app/assets/javascripts/notes/components/noteable_discussion.vue b/app/assets/javascripts/notes/components/noteable_discussion.vue
index e0b1f7a8c6a..493beb8cea9 100644
--- a/app/assets/javascripts/notes/components/noteable_discussion.vue
+++ b/app/assets/javascripts/notes/components/noteable_discussion.vue
@@ -290,9 +290,6 @@ export default {
parent: this.$el,
});
},
- deleteNoteHandler(note) {
- this.$emit('noteDeleted', this.discussion, note);
- },
onStartReplying(discussionId) {
if (this.discussion.id === discussionId) {
this.showReplyForm();
@@ -329,7 +326,6 @@ export default {
:is-overview-tab="isOverviewTab"
:should-scroll-to-note="shouldScrollToNote"
@startReplying="showReplyForm"
- @deleteNote="deleteNoteHandler"
>
<template #avatar-badge>
<slot name="avatar-badge"></slot>
diff --git a/app/assets/javascripts/notes/stores/mutations.js b/app/assets/javascripts/notes/stores/mutations.js
index 966f4184780..a995b9fa214 100644
--- a/app/assets/javascripts/notes/stores/mutations.js
+++ b/app/assets/javascripts/notes/stores/mutations.js
@@ -318,11 +318,6 @@ export default {
const note = noteData;
const selectedDiscussion = state.discussions.find((disc) => disc.id === note.id);
note.expanded = true; // override expand flag to prevent collapse
- if (note.diff_file) {
- Object.assign(note, {
- file_hash: note.diff_file.file_hash,
- });
- }
Object.assign(selectedDiscussion, { ...note });
},
diff --git a/app/assets/javascripts/observability/client.js b/app/assets/javascripts/observability/client.js
index da8837c21da..54ca8311621 100644
--- a/app/assets/javascripts/observability/client.js
+++ b/app/assets/javascripts/observability/client.js
@@ -246,22 +246,18 @@ async function fetchOperations(operationsUrl, serviceName) {
}
}
-async function fetchMetrics() {
- // TODO replace mocks with API calls https://gitlab.com/gitlab-org/opstrace/opstrace/-/issues/2469
- /* eslint-disable @gitlab/require-i18n-strings */
- return {
- metrics: [
- { name: 'metric A', description: 'a counter metric called A', type: 'COUNTER' },
- { name: 'metric B', description: 'a gauge metric called B', type: 'GAUGE' },
- { name: 'metric C', description: 'a histogram metric called C', type: 'HISTOGRAM' },
- {
- name: 'metric D',
- description: 'a exp histogram metric called D',
- type: 'EXPONENTIAL HISTOGRAM',
- },
- ],
- };
- /* eslint-enable @gitlab/require-i18n-strings */
+async function fetchMetrics(metricsUrl) {
+ try {
+ const { data } = await axios.get(metricsUrl, {
+ withCredentials: true,
+ });
+ if (!Array.isArray(data.metrics)) {
+ throw new Error('metrics are missing/invalid in the response'); // eslint-disable-line @gitlab/require-i18n-strings
+ }
+ return data;
+ } catch (e) {
+ return reportErrorAndThrow(e);
+ }
}
export function buildClient(options) {
diff --git a/app/assets/javascripts/organizations/users/graphql/organization_users.query.graphql b/app/assets/javascripts/organizations/users/graphql/organization_users.query.graphql
index 7b37186ba1a..a0b2a639401 100644
--- a/app/assets/javascripts/organizations/users/graphql/organization_users.query.graphql
+++ b/app/assets/javascripts/organizations/users/graphql/organization_users.query.graphql
@@ -3,7 +3,10 @@ query getOrganizationUsers($id: OrganizationsOrganizationID!) {
id
organizationUsers {
nodes {
- badges
+ badges {
+ text
+ variant
+ }
id
user {
id
diff --git a/app/assets/javascripts/persistent_user_callouts.js b/app/assets/javascripts/persistent_user_callouts.js
index c03c00c06aa..bba8e1f7ba5 100644
--- a/app/assets/javascripts/persistent_user_callouts.js
+++ b/app/assets/javascripts/persistent_user_callouts.js
@@ -23,6 +23,7 @@ const PERSISTENT_USER_CALLOUTS = [
'.js-geo-migrate-hashed-storage-callout',
'.js-unlimited-members-during-trial-alert',
'.js-branch-rules-info-callout',
+ '.js-new-nav-for-everyone-callout',
'.js-namespace-over-storage-users-combined-alert',
];
diff --git a/app/assets/javascripts/profile/preferences/components/profile_preferences.vue b/app/assets/javascripts/profile/preferences/components/profile_preferences.vue
index aa30192b74b..2fc1f99c183 100644
--- a/app/assets/javascripts/profile/preferences/components/profile_preferences.vue
+++ b/app/assets/javascripts/profile/preferences/components/profile_preferences.vue
@@ -5,9 +5,9 @@ import { INTEGRATION_VIEW_CONFIGS, i18n } from '../constants';
import IntegrationView from './integration_view.vue';
function updateClasses(bodyClasses = '', applicationTheme, layout) {
- // Remove body class for any previous theme, re-add current one
- document.body.classList.remove(...bodyClasses.split(' '));
- document.body.classList.add(applicationTheme);
+ // Remove documentElement class for any previous theme, re-add current one
+ document.documentElement.classList.remove(...bodyClasses.split(' '));
+ document.documentElement.classList.add(applicationTheme);
// Toggle container-fluid class
if (layout === 'fluid') {
diff --git a/app/assets/javascripts/projects/settings/init_access_dropdown.js b/app/assets/javascripts/projects/settings/init_access_dropdown.js
index 102b1846453..b02a33675ee 100644
--- a/app/assets/javascripts/projects/settings/init_access_dropdown.js
+++ b/app/assets/javascripts/projects/settings/init_access_dropdown.js
@@ -22,6 +22,7 @@ export const initAccessDropdown = (el, options) => {
data() {
return { preselected };
},
+ disabled,
methods: {
setPreselectedItems(items) {
this.preselected = items;
diff --git a/app/assets/javascripts/protected_branches/protected_branch_edit.js b/app/assets/javascripts/protected_branches/protected_branch_edit.js
index 29034b3bc0e..66da3de516a 100644
--- a/app/assets/javascripts/protected_branches/protected_branch_edit.js
+++ b/app/assets/javascripts/protected_branches/protected_branch_edit.js
@@ -6,6 +6,10 @@ import { initToggle } from '~/toggles';
import { initAccessDropdown } from '~/projects/settings/init_access_dropdown';
import { ACCESS_LEVELS, LEVEL_TYPES } from './constants';
+const isDropdownDisabled = (dropdown) => {
+ return dropdown?.$options.disabled === '';
+};
+
export default class ProtectedBranchEdit {
constructor(options) {
this.hasLicense = options.hasLicense;
@@ -104,6 +108,9 @@ export default class ProtectedBranchEdit {
}
initSelectedItems(dropdown, accessLevel) {
+ if (isDropdownDisabled(dropdown)) {
+ return;
+ }
this.selectedItems[accessLevel] = dropdown.preselected.map((item) => {
if (item.type === LEVEL_TYPES.USER) return { id: item.id, user_id: item.user_id };
if (item.type === LEVEL_TYPES.ROLE) return { id: item.id, access_level: item.access_level };
@@ -183,7 +190,10 @@ export default class ProtectedBranchEdit {
};
});
- this.selectedItems[accessLevel] = itemsToAdd;
- this[`${accessLevel}_dropdown`]?.setPreselectedItems(itemsToAdd);
+ const dropdown = this[`${accessLevel}_dropdown`];
+ if (!isDropdownDisabled(dropdown)) {
+ this.selectedItems[accessLevel] = itemsToAdd;
+ dropdown?.setPreselectedItems(itemsToAdd);
+ }
}
}
diff --git a/app/assets/javascripts/super_sidebar/components/user_menu.vue b/app/assets/javascripts/super_sidebar/components/user_menu.vue
index 891e883b6c0..5712b716f48 100644
--- a/app/assets/javascripts/super_sidebar/components/user_menu.vue
+++ b/app/assets/javascripts/super_sidebar/components/user_menu.vue
@@ -8,7 +8,6 @@ import {
} from '@gitlab/ui';
import SafeHtml from '~/vue_shared/directives/safe_html';
import { s__, __, sprintf } from '~/locale';
-import NewNavToggle from '~/nav/components/new_nav_toggle.vue';
import Tracking from '~/tracking';
import PersistentUserCallout from '~/persistent_user_callout';
import { USER_MENU_TRACKING_DEFAULTS, DROPDOWN_Y_OFFSET, IMPERSONATING_OFFSET } from '../constants';
@@ -39,14 +38,13 @@ export default {
GlDisclosureDropdownGroup,
GlDisclosureDropdownItem,
GlButton,
- NewNavToggle,
UserMenuProfileItem,
},
directives: {
SafeHtml,
},
mixins: [Tracking.mixin()],
- inject: ['toggleNewNavEndpoint', 'isImpersonating'],
+ inject: ['isImpersonating'],
props: {
data: {
required: true,
@@ -301,13 +299,6 @@ export default {
/>
</gl-disclosure-dropdown-group>
- <gl-disclosure-dropdown-group bordered>
- <template #group-label>
- <span class="gl-font-sm">{{ $options.i18n.newNavigation.sectionTitle }}</span>
- </template>
- <new-nav-toggle :endpoint="toggleNewNavEndpoint" enabled new-navigation />
- </gl-disclosure-dropdown-group>
-
<gl-disclosure-dropdown-group
v-if="data.can_sign_out"
bordered
diff --git a/app/assets/javascripts/super_sidebar/super_sidebar_bundle.js b/app/assets/javascripts/super_sidebar/super_sidebar_bundle.js
index d0d98ef3808..9e540175b48 100644
--- a/app/assets/javascripts/super_sidebar/super_sidebar_bundle.js
+++ b/app/assets/javascripts/super_sidebar/super_sidebar_bundle.js
@@ -66,13 +66,7 @@ export const initSuperSidebar = () => {
if (!el) return false;
- const {
- rootPath,
- sidebar,
- toggleNewNavEndpoint,
- forceDesktopExpandedSidebar,
- commandPalette,
- } = el.dataset;
+ const { rootPath, sidebar, forceDesktopExpandedSidebar, commandPalette } = el.dataset;
bindSuperSidebarCollapsedEvents(forceDesktopExpandedSidebar);
initSuperSidebarCollapsedState(parseBoolean(forceDesktopExpandedSidebar));
@@ -98,7 +92,6 @@ export const initSuperSidebar = () => {
name: 'SuperSidebarRoot',
provide: {
rootPath,
- toggleNewNavEndpoint,
isImpersonating,
...getTrialStatusWidgetData(sidebarData),
commandPaletteCommands,
diff --git a/app/assets/javascripts/vue_shared/components/diff_stats_dropdown.vue b/app/assets/javascripts/vue_shared/components/diff_stats_dropdown.vue
index f62bfb551df..70daac311c7 100644
--- a/app/assets/javascripts/vue_shared/components/diff_stats_dropdown.vue
+++ b/app/assets/javascripts/vue_shared/components/diff_stats_dropdown.vue
@@ -1,11 +1,5 @@
<script>
-import {
- GlDropdown,
- GlDropdownItem,
- GlDropdownText,
- GlSearchBoxByType,
- GlSprintf,
-} from '@gitlab/ui';
+import { GlDisclosureDropdown, GlIcon, GlSearchBoxByType, GlSprintf } from '@gitlab/ui';
import fuzzaldrinPlus from 'fuzzaldrin-plus';
import { __, n__, s__, sprintf } from '~/locale';
@@ -16,12 +10,16 @@ export const i18n = {
searchFiles: __('Search files'),
};
+const variantCssColorMap = {
+ success: 'gl-text-green-500',
+ danger: 'gl-text-red-500',
+};
+
export default {
i18n,
components: {
- GlDropdown,
- GlDropdownItem,
- GlDropdownText,
+ GlDisclosureDropdown,
+ GlIcon,
GlSearchBoxByType,
GlSprintf,
},
@@ -54,6 +52,15 @@ export default {
? fuzzaldrinPlus.filter(this.files, this.search, { key: 'name' })
: this.files;
},
+ dropdownItems() {
+ return this.filteredFiles.map((file) => {
+ return {
+ ...file,
+ text: file.name || this.$options.i18n.noFileNameAvailable,
+ iconColor: variantCssColorMap[file.iconColor],
+ };
+ });
+ },
messageChanged() {
return sprintf(
n__(
@@ -64,21 +71,21 @@ export default {
{ count: this.changed },
);
},
-
- additionsText() {
- return n__('Diffs|%d addition', 'Diffs|%d additions', this.added);
- },
- deletionsText() {
- return n__('Diffs|%d deletion', 'Diffs|%d deletions', this.deleted);
- },
},
methods: {
- jumpToFile(fileHash) {
- window.location.hash = fileHash;
- },
focusInput() {
this.$refs.search.focusInput();
},
+ focusFirstItem() {
+ if (!this.filteredFiles.length) return;
+ this.$el.querySelector('.gl-new-dropdown-item:first-child').focus();
+ },
+ additionsText(numberOfChanges = this.added) {
+ return n__('Diffs|%d addition', 'Diffs|%d additions', numberOfChanges);
+ },
+ deletionsText(numberOfChanges = this.deleted) {
+ return n__('Diffs|%d deletion', 'Diffs|%d deletions', numberOfChanges);
+ },
},
};
</script>
@@ -87,15 +94,15 @@ export default {
<div>
<gl-sprintf :message="messageChanged">
<template #dropdown="{ content: dropdownText }">
- <gl-dropdown
+ <gl-disclosure-dropdown
+ :toggle-text="dropdownText"
+ :items="dropdownItems"
category="tertiary"
variant="confirm"
- :text="dropdownText"
data-testid="diff-stats-dropdown"
class="gl-vertical-align-baseline"
toggle-class="gl-px-0! gl-font-weight-bold!"
- menu-class="gl-w-auto!"
- no-flip
+ fluid-width
@shown="focusInput"
>
<template #header>
@@ -103,35 +110,38 @@ export default {
ref="search"
v-model.trim="search"
:placeholder="$options.i18n.searchFiles"
+ class="gl-mx-3 gl-my-4"
+ @keydown.down="focusFirstItem"
/>
+ <span v-if="!filteredFiles.length" class="gl-mx-3">
+ {{ $options.i18n.noFilesFound }}
+ </span>
</template>
- <gl-dropdown-item
- v-for="file in filteredFiles"
- :key="file.href"
- :icon-name="file.icon"
- :icon-color="file.iconColor"
- @click="jumpToFile(file.href)"
- >
- <div class="gl-display-flex">
- <span v-if="file.name" class="gl-font-weight-bold gl-mr-3 gl-text-truncate">{{
- file.name
- }}</span>
- <span v-else class="gl-mr-3 gl-font-weight-bold gl-font-style-italic gl-gray-400">{{
- $options.i18n.noFileNameAvailable
- }}</span>
- <span class="gl-ml-auto gl-white-space-nowrap">
- <span class="gl-text-green-600">+{{ file.added }}</span>
- <span class="gl-text-red-500">-{{ file.removed }}</span>
- </span>
+ <template #list-item="{ item }">
+ <div class="gl-display-flex gl-gap-3 gl-align-items-center">
+ <gl-icon :name="item.icon" :class="item.iconColor" />
+ <div class="gl-flex-grow-1">
+ <div class="gl-display-flex">
+ <span
+ class="gl-font-weight-bold gl-mr-3 gl-flex-grow-1"
+ :class="item.name ? 'gl-text-truncate' : 'gl-font-style-italic gl-gray-400'"
+ >{{ item.text }}</span
+ >
+ <span class="gl-ml-auto gl-white-space-nowrap" aria-hidden="true">
+ <span class="gl-text-green-600">+{{ item.added }}</span>
+ <span class="gl-text-red-500">-{{ item.removed }}</span>
+ </span>
+ <span class="gl-sr-only"
+ >{{ additionsText(item.added) }}, {{ deletionsText(item.removed) }}</span
+ >
+ </div>
+ <div class="gl-text-gray-700 gl-overflow-hidden gl-text-overflow-ellipsis">
+ {{ item.path }}
+ </div>
+ </div>
</div>
- <div class="gl-text-gray-700 gl-overflow-hidden gl-text-overflow-ellipsis">
- {{ file.path }}
- </div>
- </gl-dropdown-item>
- <gl-dropdown-text v-if="!filteredFiles.length">
- {{ $options.i18n.noFilesFound }}
- </gl-dropdown-text>
- </gl-dropdown>
+ </template>
+ </gl-disclosure-dropdown>
</template>
</gl-sprintf>
<span
@@ -140,12 +150,20 @@ export default {
>
<gl-sprintf :message="$options.i18n.messageAdditionsDeletions">
<template #additions>
- <span class="gl-text-green-600 gl-font-weight-bold">{{ additionsText }}</span>
+ <span class="gl-text-green-600 gl-font-weight-bold">{{ additionsText() }}</span>
</template>
<template #deletions>
- <span class="gl-text-red-500 gl-font-weight-bold">{{ deletionsText }}</span>
+ <span class="gl-text-red-500 gl-font-weight-bold">{{ deletionsText() }}</span>
</template>
</gl-sprintf>
</span>
</div>
</template>
+
+<style scoped>
+/* TODO: Use max-height prop when gitlab-ui got updated.
+See https://gitlab.com/gitlab-org/gitlab-ui/-/issues/2374 */
+::v-deep .gl-new-dropdown-inner {
+ max-height: 310px;
+}
+</style>
diff --git a/app/assets/javascripts/vue_shared/components/list_selector/constants.js b/app/assets/javascripts/vue_shared/components/list_selector/constants.js
index 2e58527a2ea..cff9c56a1c0 100644
--- a/app/assets/javascripts/vue_shared/components/list_selector/constants.js
+++ b/app/assets/javascripts/vue_shared/components/list_selector/constants.js
@@ -1,6 +1,6 @@
import { __ } from '~/locale';
export const CONFIG = {
- users: { title: __('Users'), icon: 'user', filterKey: 'username' },
+ users: { title: __('Users'), icon: 'user', filterKey: 'username', showNamespaceDropdown: true },
groups: { title: __('Groups'), icon: 'group', filterKey: 'name' },
};
diff --git a/app/assets/javascripts/vue_shared/components/list_selector/index.vue b/app/assets/javascripts/vue_shared/components/list_selector/index.vue
index 6813d9ca077..b8480a0c496 100644
--- a/app/assets/javascripts/vue_shared/components/list_selector/index.vue
+++ b/app/assets/javascripts/vue_shared/components/list_selector/index.vue
@@ -1,13 +1,23 @@
<script>
import { GlCard, GlIcon, GlCollapsibleListbox, GlSearchBoxByType } from '@gitlab/ui';
-import usersAutocompleteQuery from '~/graphql_shared/queries/users_autocomplete.query.graphql';
+import { parseBoolean } from '~/lib/utils/common_utils';
+import { createAlert } from '~/alert';
+import { __ } from '~/locale';
import groupsAutocompleteQuery from '~/graphql_shared/queries/groups_autocomplete.query.graphql';
+import Api from '~/api';
import UserItem from './user_item.vue';
import GroupItem from './group_item.vue';
import { CONFIG } from './constants';
+const I18N = {
+ allGroups: __('All groups'),
+ projectGroups: __('Project groups'),
+ apiErrorMessage: __('An error occurred while fetching. Please try again.'),
+};
+
export default {
name: 'ListSelector',
+ i18n: I18N,
components: {
GlCard,
GlIcon,
@@ -33,11 +43,16 @@ export default {
required: false,
default: null,
},
+ groupPath: {
+ type: String,
+ required: false,
+ default: null,
+ },
},
data() {
return {
searchValue: '',
- isProject: true, // TODO: implement a way to distinguish between project/group
+ isProjectNamespace: 'true',
selected: [],
items: [],
};
@@ -46,39 +61,44 @@ export default {
config() {
return CONFIG[this.type];
},
- searchItems() {
- return this.items;
- },
isUserVariant() {
return this.type === 'users';
},
component() {
return this.isUserVariant ? UserItem : GroupItem;
},
+ namespaceDropdownText() {
+ return parseBoolean(this.isProjectNamespace)
+ ? this.$options.i18n.projectGroups
+ : this.$options.i18n.allGroups;
+ },
},
methods: {
async handleSearchInput(search) {
this.$refs.results.open();
- if (this.isUserVariant) {
- this.items = await this.fetchUsersBySearchTerm(search);
- } else {
- this.items = await this.fetchGroupsBySearchTerm(search);
+
+ try {
+ if (this.isUserVariant) {
+ this.items = await this.fetchUsersBySearchTerm(search);
+ } else {
+ this.items = await this.fetchGroupsBySearchTerm(search);
+ }
+ } catch (e) {
+ createAlert({
+ message: this.$options.i18n.apiErrorMessage,
+ });
}
},
- fetchUsersBySearchTerm(search) {
- const namespace = this.isProject ? 'project' : 'group';
- return this.$apollo
- .query({
- query: usersAutocompleteQuery,
- variables: { fullPath: this.projectPath, search, isProject: this.isProject },
- })
- .then(({ data }) =>
- data[namespace]?.autocompleteUsers.map((user) => ({
- text: user.name,
- value: user.username,
- ...user,
- })),
- );
+ async fetchUsersBySearchTerm(search) {
+ let users = [];
+ if (parseBoolean(this.isProjectNamespace)) {
+ users = await Api.projectUsers(this.projectPath, search);
+ } else {
+ const groupMembers = await Api.groupMembers(this.groupPath, { query: search });
+ users = groupMembers?.data || [];
+ }
+
+ return users?.map((user) => ({ text: user.name, value: user.username, ...user }));
},
fetchGroupsBySearchTerm(search) {
return this.$apollo
@@ -95,7 +115,7 @@ export default {
);
},
getItemByKey(key) {
- return this.searchItems.find((item) => item[this.config.filterKey] === key);
+ return this.items.find((item) => item[this.config.filterKey] === key);
},
handleSelectItem(key) {
this.$emit('select', this.getItemByKey(key));
@@ -103,7 +123,15 @@ export default {
handleDeleteItem(key) {
this.$emit('delete', key);
},
+ handleSelectNamespace() {
+ this.items = [];
+ this.searchValue = '';
+ },
},
+ namespaceOptions: [
+ { text: I18N.projectGroups, value: 'true' },
+ { text: I18N.allGroups, value: 'false' },
+ ],
};
</script>
@@ -118,28 +146,38 @@ export default {
></template
>
- <gl-collapsible-listbox
- ref="results"
- v-model="selected"
- class="list-selector gl-mb-4 gl-display-block"
- :items="searchItems"
- multiple
- @shown="$refs.search.focusInput()"
- >
- <template #toggle>
- <gl-search-box-by-type
- ref="search"
- v-model="searchValue"
- autofocus
- debounce="500"
- @input="handleSearchInput"
- />
- </template>
+ <div class="gl-display-flex gl-gap-3" :class="{ 'gl-mb-4': selectedItems.length }">
+ <gl-collapsible-listbox
+ ref="results"
+ v-model="selected"
+ class="list-selector gl-display-block gl-flex-grow-1"
+ :items="items"
+ multiple
+ @shown="$refs.search.focusInput()"
+ >
+ <template #toggle>
+ <gl-search-box-by-type
+ ref="search"
+ v-model="searchValue"
+ autofocus
+ debounce="500"
+ @input="handleSearchInput"
+ />
+ </template>
+
+ <template #list-item="{ item }">
+ <component :is="component" :data="item" @select="handleSelectItem" />
+ </template>
+ </gl-collapsible-listbox>
- <template #list-item="{ item }">
- <component :is="component" :data="item" @select="handleSelectItem" />
- </template>
- </gl-collapsible-listbox>
+ <gl-collapsible-listbox
+ v-if="config.showNamespaceDropdown"
+ v-model="isProjectNamespace"
+ :toggle-text="namespaceDropdownText"
+ :items="$options.namespaceOptions"
+ @select="handleSelectNamespace"
+ />
+ </div>
<component
:is="component"
diff --git a/app/assets/javascripts/vue_shared/issuable/show/components/issuable_body.vue b/app/assets/javascripts/vue_shared/issuable/show/components/issuable_body.vue
index 45fde45f516..dae3ddfe016 100644
--- a/app/assets/javascripts/vue_shared/issuable/show/components/issuable_body.vue
+++ b/app/assets/javascripts/vue_shared/issuable/show/components/issuable_body.vue
@@ -74,6 +74,11 @@ export default {
required: false,
default: 0,
},
+ workspaceType: {
+ type: String,
+ required: false,
+ default: '',
+ },
},
computed: {
isUpdated() {
@@ -161,6 +166,7 @@ export default {
:issuable="issuable"
:status-icon="statusIcon"
:enable-edit="enableEdit"
+ :workspace-type="workspaceType"
@edit-issuable="$emit('edit-issuable', $event)"
>
<template #status-badge>
diff --git a/app/assets/javascripts/vue_shared/issuable/show/components/issuable_show_root.vue b/app/assets/javascripts/vue_shared/issuable/show/components/issuable_show_root.vue
index 3878c16c8d0..040f49c7c25 100644
--- a/app/assets/javascripts/vue_shared/issuable/show/components/issuable_show_root.vue
+++ b/app/assets/javascripts/vue_shared/issuable/show/components/issuable_show_root.vue
@@ -147,6 +147,7 @@ export default {
:description-help-path="descriptionHelpPath"
:task-list-update-path="taskListUpdatePath"
:task-list-lock-version="taskListLockVersion"
+ :workspace-type="workspaceType"
@edit-issuable="$emit('edit-issuable', $event)"
@task-list-update-success="$emit('task-list-update-success', $event)"
@task-list-update-failure="$emit('task-list-update-failure')"
diff --git a/app/assets/javascripts/vue_shared/issuable/show/components/issuable_title.vue b/app/assets/javascripts/vue_shared/issuable/show/components/issuable_title.vue
index 3aef7d141e0..5387e39e3eb 100644
--- a/app/assets/javascripts/vue_shared/issuable/show/components/issuable_title.vue
+++ b/app/assets/javascripts/vue_shared/issuable/show/components/issuable_title.vue
@@ -1,5 +1,6 @@
<script>
import { GlIcon, GlBadge, GlButton, GlIntersectionObserver, GlTooltipDirective } from '@gitlab/ui';
+import ConfidentialityBadge from '~/vue_shared/components/confidentiality_badge.vue';
import SafeHtml from '~/vue_shared/directives/safe_html';
import { STATUS_OPEN } from '~/issues/constants';
import { __ } from '~/locale';
@@ -13,6 +14,7 @@ export default {
GlBadge,
GlButton,
GlIntersectionObserver,
+ ConfidentialityBadge,
},
directives: {
GlTooltip: GlTooltipDirective,
@@ -31,6 +33,11 @@ export default {
type: Boolean,
required: true,
},
+ workspaceType: {
+ type: String,
+ required: false,
+ default: '',
+ },
},
data() {
return {
@@ -89,6 +96,12 @@ export default {
<slot name="status-badge"></slot>
</span>
</gl-badge>
+ <confidentiality-badge
+ v-if="issuable.confidential"
+ class="gl-white-space-nowrap gl-mr-3 gl-align-self-center"
+ :issuable-type="issuable.type"
+ :workspace-type="workspaceType"
+ />
<p
class="gl-font-weight-bold gl-overflow-hidden gl-white-space-nowrap gl-text-overflow-ellipsis gl-my-0"
:title="issuable.title"
diff --git a/app/assets/javascripts/work_items/components/work_item_type_icon.vue b/app/assets/javascripts/work_items/components/work_item_type_icon.vue
index 76a73093206..5426f3965b3 100644
--- a/app/assets/javascripts/work_items/components/work_item_type_icon.vue
+++ b/app/assets/javascripts/work_items/components/work_item_type_icon.vue
@@ -36,11 +36,6 @@ export default {
return this.workItemType.toUpperCase().split(' ').join('_');
},
iconName() {
- // TODO Delete this conditional once we have an `issue-type-epic` icon
- if (this.workItemIconName === 'issue-type-epic') {
- return 'epic';
- }
-
return (
this.workItemIconName ||
WORK_ITEMS_TYPE_MAP[this.workItemTypeUppercase]?.icon ||
diff --git a/app/assets/javascripts/work_items/constants.js b/app/assets/javascripts/work_items/constants.js
index 2f2401bd9b3..e2dbfeb55a5 100644
--- a/app/assets/javascripts/work_items/constants.js
+++ b/app/assets/javascripts/work_items/constants.js
@@ -35,6 +35,7 @@ export const WORK_ITEM_TYPE_ENUM_TEST_CASE = 'TEST_CASE';
export const WORK_ITEM_TYPE_ENUM_REQUIREMENTS = 'REQUIREMENTS';
export const WORK_ITEM_TYPE_ENUM_OBJECTIVE = 'OBJECTIVE';
export const WORK_ITEM_TYPE_ENUM_KEY_RESULT = 'KEY_RESULT';
+export const WORK_ITEM_TYPE_ENUM_EPIC = 'EPIC';
export const WORK_ITEM_TYPE_VALUE_EPIC = 'Epic';
export const WORK_ITEM_TYPE_VALUE_INCIDENT = 'Incident';
@@ -185,6 +186,11 @@ export const WORK_ITEMS_TYPE_MAP = {
name: s__('WorkItem|Key result'),
value: WORK_ITEM_TYPE_VALUE_KEY_RESULT,
},
+ [WORK_ITEM_TYPE_ENUM_EPIC]: {
+ icon: `epic`,
+ name: s__('WorkItem|Epic'),
+ value: WORK_ITEM_TYPE_VALUE_EPIC,
+ },
};
export const WORK_ITEMS_TREE_TEXT_MAP = {