diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-08-09 03:08:46 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-08-09 03:08:46 +0300 |
commit | 4596c2f5a5aef62aee84c24c26d9dc8db538ef3e (patch) | |
tree | c8d6979bc588b9f7c8553c9ed1603a550a9d46a2 /app/assets/javascripts/work_items | |
parent | 929b0ad5007d1b9a006b8b9b477f01702f9a780f (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/work_items')
6 files changed, 117 insertions, 17 deletions
diff --git a/app/assets/javascripts/work_items/components/notes/work_item_note.vue b/app/assets/javascripts/work_items/components/notes/work_item_note.vue index a2667a379e1..92560f2da9e 100644 --- a/app/assets/javascripts/work_items/components/notes/work_item_note.vue +++ b/app/assets/javascripts/work_items/components/notes/work_item_note.vue @@ -3,7 +3,7 @@ import { GlAvatarLink, GlAvatar } from '@gitlab/ui'; import * as Sentry from '@sentry/browser'; import toast from '~/vue_shared/plugins/global_toast'; import { __ } from '~/locale'; -import { i18n, TRACKING_CATEGORY_SHOW, WIDGET_TYPE_ASSIGNEES } from '~/work_items/constants'; +import { i18n, TRACKING_CATEGORY_SHOW } from '~/work_items/constants'; import Tracking from '~/tracking'; import { updateDraft, clearDraft } from '~/lib/utils/autosave'; import { renderMarkdown } from '~/notes/utils'; @@ -17,6 +17,7 @@ import NoteActions from '~/work_items/components/notes/work_item_note_actions.vu import updateWorkItemMutation from '~/work_items/graphql/update_work_item.mutation.graphql'; import updateWorkItemNoteMutation from '../../graphql/notes/update_work_item_note.mutation.graphql'; import workItemByIidQuery from '../../graphql/work_item_by_iid.query.graphql'; +import { isAssigneesWidget } from '../../utils'; import WorkItemCommentForm from './work_item_comment_form.vue'; import WorkItemNoteAwardsList from './work_item_note_awards_list.vue'; @@ -228,8 +229,6 @@ export default { newAssignees = [...this.assignees, this.author]; } - const isAssigneesWidget = (widget) => widget.type === WIDGET_TYPE_ASSIGNEES; - const assigneesWidgetIndex = this.workItem.widgets.findIndex(isAssigneesWidget); const editedWorkItemWidgets = [...this.workItem.widgets]; diff --git a/app/assets/javascripts/work_items/components/work_item_labels.vue b/app/assets/javascripts/work_items/components/work_item_labels.vue index 5bfb65fe91c..1405a12a101 100644 --- a/app/assets/javascripts/work_items/components/work_item_labels.vue +++ b/app/assets/javascripts/work_items/components/work_item_labels.vue @@ -9,13 +9,8 @@ import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants'; import { isScopedLabel } from '~/lib/utils/common_utils'; import updateWorkItemMutation from '../graphql/update_work_item.mutation.graphql'; import workItemByIidQuery from '../graphql/work_item_by_iid.query.graphql'; - -import { - i18n, - I18N_WORK_ITEM_ERROR_FETCHING_LABELS, - TRACKING_CATEGORY_SHOW, - WIDGET_TYPE_LABELS, -} from '../constants'; +import { i18n, I18N_WORK_ITEM_ERROR_FETCHING_LABELS, TRACKING_CATEGORY_SHOW } from '../constants'; +import { isLabelsWidget } from '../utils'; function isTokenSelectorElement(el) { return ( @@ -127,7 +122,7 @@ export default { return this.$apollo.queries.searchLabels.loading; }, labelsWidget() { - return this.workItem?.widgets?.find((widget) => widget.type === WIDGET_TYPE_LABELS); + return this.workItem?.widgets?.find(isLabelsWidget); }, labels() { return this.labelsWidget?.labels?.nodes || []; diff --git a/app/assets/javascripts/work_items/list/components/work_items_list_app.vue b/app/assets/javascripts/work_items/list/components/work_items_list_app.vue index 4180d484357..fe7cb719bbb 100644 --- a/app/assets/javascripts/work_items/list/components/work_items_list_app.vue +++ b/app/assets/javascripts/work_items/list/components/work_items_list_app.vue @@ -1,8 +1,11 @@ <script> +import * as Sentry from '@sentry/browser'; import { STATUS_OPEN } from '~/issues/constants'; -import { __ } from '~/locale'; +import { __, s__ } from '~/locale'; import IssuableList from '~/vue_shared/issuable/list/components/issuable_list_root.vue'; import { issuableListTabs } from '~/vue_shared/issuable/list/constants'; +import { STATE_CLOSED } from '../../constants'; +import getWorkItemsQuery from '../queries/get_work_items.query.graphql'; export default { i18n: { @@ -12,26 +15,59 @@ export default { components: { IssuableList, }, + inject: ['fullPath'], data() { return { - issues: [], + error: undefined, searchTokens: [], sortOptions: [], state: STATUS_OPEN, + workItems: [], }; }, + apollo: { + workItems: { + query: getWorkItemsQuery, + variables() { + return { + fullPath: this.fullPath, + }; + }, + update(data) { + return data.group.workItems.nodes ?? []; + }, + error(error) { + this.error = s__( + 'WorkItem|Something went wrong when fetching work items. Please try again.', + ); + Sentry.captureException(error); + }, + }, + }, + methods: { + getStatus(issue) { + return issue.state === STATE_CLOSED ? __('Closed') : undefined; + }, + }, }; </script> <template> <issuable-list :current-tab="state" - :issuables="issues" + :error="error" + :issuables="workItems" namespace="work-items" recent-searches-storage-key="issues" :search-input-placeholder="$options.i18n.searchPlaceholder" :search-tokens="searchTokens" + show-work-item-type-icon :sort-options="sortOptions" :tabs="$options.issuableListTabs" - /> + @dismiss-alert="error = undefined" + > + <template #status="{ issuable }"> + {{ getStatus(issuable) }} + </template> + </issuable-list> </template> diff --git a/app/assets/javascripts/work_items/list/index.js b/app/assets/javascripts/work_items/list/index.js index 5b701893471..5cd38600779 100644 --- a/app/assets/javascripts/work_items/list/index.js +++ b/app/assets/javascripts/work_items/list/index.js @@ -1,5 +1,7 @@ import Vue from 'vue'; -import WorkItemsListApp from '~/work_items/list/components/work_items_list_app.vue'; +import VueApollo from 'vue-apollo'; +import createDefaultClient from '~/lib/graphql'; +import WorkItemsListApp from './components/work_items_list_app.vue'; export const mountWorkItemsListApp = () => { const el = document.querySelector('.js-work-items-list-root'); @@ -8,9 +10,17 @@ export const mountWorkItemsListApp = () => { return null; } + Vue.use(VueApollo); + return new Vue({ el, name: 'WorkItemsListRoot', + apolloProvider: new VueApollo({ + defaultClient: createDefaultClient(), + }), + provide: { + fullPath: el.dataset.fullPath, + }, render: (createComponent) => createComponent(WorkItemsListApp), }); }; diff --git a/app/assets/javascripts/work_items/list/queries/get_work_items.query.graphql b/app/assets/javascripts/work_items/list/queries/get_work_items.query.graphql new file mode 100644 index 00000000000..7ada2cf12dd --- /dev/null +++ b/app/assets/javascripts/work_items/list/queries/get_work_items.query.graphql @@ -0,0 +1,56 @@ +query getWorkItems($fullPath: ID!) { + group(fullPath: $fullPath) { + id + workItems { + nodes { + id + author { + id + avatarUrl + name + username + webUrl + } + closedAt + confidential + createdAt + iid + reference(full: true) + state + title + updatedAt + webUrl + widgets { + ... on WorkItemWidgetAssignees { + assignees { + nodes { + id + avatarUrl + name + username + webUrl + } + } + type + } + ... on WorkItemWidgetLabels { + allowsScopedLabels + labels { + nodes { + id + color + description + title + } + } + type + } + } + workItemType { + id + name + } + } + } + } +} diff --git a/app/assets/javascripts/work_items/utils.js b/app/assets/javascripts/work_items/utils.js index 81dbe56b2ea..5a882977bc2 100644 --- a/app/assets/javascripts/work_items/utils.js +++ b/app/assets/javascripts/work_items/utils.js @@ -1,4 +1,8 @@ -import { WIDGET_TYPE_HIERARCHY } from '~/work_items/constants'; +import { WIDGET_TYPE_ASSIGNEES, WIDGET_TYPE_HIERARCHY, WIDGET_TYPE_LABELS } from './constants'; + +export const isAssigneesWidget = (widget) => widget.type === WIDGET_TYPE_ASSIGNEES; + +export const isLabelsWidget = (widget) => widget.type === WIDGET_TYPE_LABELS; export const findHierarchyWidgets = (widgets) => widgets?.find((widget) => widget.type === WIDGET_TYPE_HIERARCHY); |