diff options
Diffstat (limited to 'app/assets/javascripts/issuable')
6 files changed, 61 insertions, 34 deletions
diff --git a/app/assets/javascripts/issuable/components/status_box.vue b/app/assets/javascripts/issuable/components/status_box.vue index 799c0a18444..0d7d0f020dd 100644 --- a/app/assets/javascripts/issuable/components/status_box.vue +++ b/app/assets/javascripts/issuable/components/status_box.vue @@ -4,7 +4,13 @@ import Vue from 'vue'; import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import { fetchPolicies } from '~/lib/graphql'; import { __ } from '~/locale'; -import { STATUS_CLOSED, STATUS_OPEN, TYPE_ISSUE, TYPE_MERGE_REQUEST } from '~/issues/constants'; +import { + STATUS_CLOSED, + STATUS_OPEN, + TYPE_ISSUE, + TYPE_MERGE_REQUEST, + TYPE_EPIC, +} from '~/issues/constants'; export const badgeState = Vue.observable({ state: '', @@ -18,17 +24,22 @@ const CLASSES = { merged: 'issuable-status-badge-merged', }; -const ISSUE_ICONS = { - opened: 'issues', - locked: 'issues', - closed: 'issue-closed', -}; - -const MERGE_REQUEST_ICONS = { - opened: 'merge-request-open', - locked: 'merge-request-open', - closed: 'merge-request-close', - merged: 'merge', +const ICONS = { + [TYPE_EPIC]: { + opened: 'epic', + closed: 'epic-closed', + }, + [TYPE_ISSUE]: { + opened: 'issues', + locked: 'issues', + closed: 'issue-closed', + }, + [TYPE_MERGE_REQUEST]: { + opened: 'merge-request-open', + locked: 'merge-request-open', + closed: 'merge-request-close', + merged: 'merge', + }, }; const STATUS = { @@ -91,10 +102,8 @@ export default { return STATUS[this.state]; }, badgeIcon() { - if (this.issuableType === TYPE_ISSUE) { - return ISSUE_ICONS[this.state]; - } - return MERGE_REQUEST_ICONS[this.state]; + const type = this.issuableType || TYPE_MERGE_REQUEST; + return ICONS[type][this.state]; }, }, created() { @@ -126,7 +135,7 @@ export default { <template> <gl-badge - class="issuable-status-badge gl-mr-3" + class="issuable-status-badge gl-mr-3 gl-align-self-center" :class="badgeClass" :variant="badgeVariant" :aria-label="badgeText" diff --git a/app/assets/javascripts/issuable/issuable_form.js b/app/assets/javascripts/issuable/issuable_form.js index a1525ad2bec..1c1acddb90b 100644 --- a/app/assets/javascripts/issuable/issuable_form.js +++ b/app/assets/javascripts/issuable/issuable_form.js @@ -7,6 +7,9 @@ import { queryToObject, objectToQuery } from '~/lib/utils/url_utility'; import UsersSelect from '~/users_select'; import ZenMode from '~/zen_mode'; import { containsSensitiveToken, confirmSensitiveAction, i18n } from '~/lib/utils/secret_detection'; +import { trackSavedUsingEditor } from '~/vue_shared/components/markdown/tracking'; +import { EDITING_MODE_CONTENT_EDITOR } from '~/vue_shared/constants'; +import { ISSUE_NOTEABLE_TYPE, MERGE_REQUEST_NOTEABLE_TYPE } from '~/notes/constants'; const MR_SOURCE_BRANCH = 'merge_request[source_branch]'; const MR_TARGET_BRANCH = 'merge_request[target_branch]'; @@ -47,6 +50,13 @@ function getFallbackKey() { return ['autosave', document.location.pathname, searchTerm].join('/'); } +function getIssuableType() { + if (document.location.pathname.includes('merge_requests')) return MERGE_REQUEST_NOTEABLE_TYPE; + if (document.location.pathname.includes('issues')) return ISSUE_NOTEABLE_TYPE; + // eslint-disable-next-line @gitlab/require-i18n-strings + return 'Other'; +} + export default class IssuableForm { static addAutosave(map, id, element, searchTerm, fallbackKey) { if (!element) return; @@ -144,6 +154,11 @@ export default class IssuableForm { async handleSubmit(event) { event.preventDefault(); + trackSavedUsingEditor( + localStorage.getItem('gl-markdown-editor-mode') === EDITING_MODE_CONTENT_EDITOR, + getIssuableType(), + ); + const form = event.target; const descriptionText = this.descriptionField().val(); diff --git a/app/assets/javascripts/issuable/issuable_label_selector.js b/app/assets/javascripts/issuable/issuable_label_selector.js index b4e277a0b31..fc6d850c341 100644 --- a/app/assets/javascripts/issuable/issuable_label_selector.js +++ b/app/assets/javascripts/issuable/issuable_label_selector.js @@ -45,6 +45,7 @@ export default () => { labelsManagePath, variant: VARIANT_EMBEDDED, workspaceType: WORKSPACE_PROJECT, + toggleAttrs: { 'data-testid': 'issuable_label_dropdown' }, }, render(createElement) { return createElement(IssuableLabelSelector); diff --git a/app/assets/javascripts/issuable/popover/components/issue_popover.vue b/app/assets/javascripts/issuable/popover/components/issue_popover.vue index 55fb3958e82..044a1bba7ad 100644 --- a/app/assets/javascripts/issuable/popover/components/issue_popover.vue +++ b/app/assets/javascripts/issuable/popover/components/issue_popover.vue @@ -28,7 +28,7 @@ export default { type: HTMLAnchorElement, required: true, }, - projectPath: { + namespacePath: { type: String, required: true, }, @@ -65,10 +65,10 @@ export default { query, update: (data) => data.project.issue, variables() { - const { projectPath, iid } = this; + const { namespacePath, iid } = this; return { - projectPath, + projectPath: namespacePath, iid, }; }, @@ -100,7 +100,7 @@ export default { <!-- eslint-disable @gitlab/vue-require-i18n-strings --> <div> <work-item-type-icon v-if="!$apollo.queries.issue.loading" :work-item-type="issue.type" /> - <span class="gl-text-secondary">{{ `${projectPath}#${iid}` }}</span> + <span class="gl-text-secondary">{{ `${namespacePath}#${iid}` }}</span> </div> <!-- eslint-enable @gitlab/vue-require-i18n-strings --> diff --git a/app/assets/javascripts/issuable/popover/components/mr_popover.vue b/app/assets/javascripts/issuable/popover/components/mr_popover.vue index af93430963e..e2c2181684f 100644 --- a/app/assets/javascripts/issuable/popover/components/mr_popover.vue +++ b/app/assets/javascripts/issuable/popover/components/mr_popover.vue @@ -19,7 +19,7 @@ export default { type: HTMLAnchorElement, required: true, }, - projectPath: { + namespacePath: { type: String, required: true, }, @@ -76,10 +76,10 @@ export default { query, update: (data) => data.project.mergeRequest, variables() { - const { projectPath, iid } = this; + const { namespacePath, iid } = this; return { - projectPath, + projectPath: namespacePath, iid, }; }, @@ -108,7 +108,7 @@ export default { <h5 v-if="!$apollo.queries.mergeRequest.loading" class="my-2">{{ title }}</h5> <!-- eslint-disable @gitlab/vue-require-i18n-strings --> <div class="gl-text-secondary"> - {{ `${projectPath}!${iid}` }} + {{ `${namespacePath}!${iid}` }} </div> <!-- eslint-enable @gitlab/vue-require-i18n-strings --> </div> diff --git a/app/assets/javascripts/issuable/popover/index.js b/app/assets/javascripts/issuable/popover/index.js index 9430419685b..58f015fe40e 100644 --- a/app/assets/javascripts/issuable/popover/index.js +++ b/app/assets/javascripts/issuable/popover/index.js @@ -4,7 +4,7 @@ import createDefaultClient from '~/lib/graphql'; import IssuePopover from './components/issue_popover.vue'; import MRPopover from './components/mr_popover.vue'; -const componentsByReferenceType = { +export const componentsByReferenceTypeMap = { issue: IssuePopover, work_item: IssuePopover, merge_request: MRPopover, @@ -26,9 +26,10 @@ const popoverMountedAttr = 'data-popover-mounted'; * Adds a MergeRequestPopover component to the body, hands over as much data as the target element has in data attributes. * loads based on data-project-path and data-iid more data about an MR from the API and sets it on the popover */ -const handleIssuablePopoverMount = ({ +export const handleIssuablePopoverMount = ({ + componentsByReferenceType = componentsByReferenceTypeMap, apolloProvider, - projectPath, + namespacePath, title, iid, referenceType, @@ -42,7 +43,7 @@ const handleIssuablePopoverMount = ({ new PopoverComponent({ propsData: { target, - projectPath, + namespacePath, iid, cachedTitle: title, }, @@ -53,7 +54,7 @@ const handleIssuablePopoverMount = ({ }, 200); // 200ms delay so not every mouseover triggers Popover + API Call }; -export default (elements) => { +export default (elements, issuablePopoverMount = handleIssuablePopoverMount) => { if (elements.length > 0) { Vue.use(VueApollo); @@ -63,15 +64,16 @@ export default (elements) => { const listenerAddedAttr = 'data-popover-listener-added'; elements.forEach((el) => { - const { projectPath, iid, referenceType } = el.dataset; + const { projectPath, groupPath, iid, referenceType } = el.dataset; const title = el.dataset.mrTitle || el.title; + const namespacePath = groupPath || projectPath; - if (!el.getAttribute(listenerAddedAttr) && projectPath && title && iid && referenceType) { + if (!el.getAttribute(listenerAddedAttr) && namespacePath && title && iid && referenceType) { el.addEventListener('mouseenter', ({ target }) => { if (!el.getAttribute(popoverMountedAttr)) { - handleIssuablePopoverMount({ + issuablePopoverMount({ apolloProvider, - projectPath, + namespacePath, title, iid, referenceType, |