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:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-11-16 12:09:18 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-11-16 12:09:18 +0300
commit14cb5b3d793c1f41c7d36e2e899d3e5e9eca148f (patch)
tree235f19919bf2a070c337f0336443fb05eacf52b2 /app/assets/javascripts/boards
parent0ab17699c88587c5872f9517b29be5f43224a8ea (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/boards')
-rw-r--r--app/assets/javascripts/boards/components/sidebar/board_sidebar_due_date.vue8
-rw-r--r--app/assets/javascripts/boards/components/sidebar/board_sidebar_labels_select.vue14
-rw-r--r--app/assets/javascripts/boards/components/sidebar/board_sidebar_subscription.vue71
-rw-r--r--app/assets/javascripts/boards/graphql/mutations/issue_set_subscription.mutation.graphql8
-rw-r--r--app/assets/javascripts/boards/stores/actions.js24
-rw-r--r--app/assets/javascripts/boards/stores/getters.js5
6 files changed, 115 insertions, 15 deletions
diff --git a/app/assets/javascripts/boards/components/sidebar/board_sidebar_due_date.vue b/app/assets/javascripts/boards/components/sidebar/board_sidebar_due_date.vue
index 19e6f8a2269..6935ead2706 100644
--- a/app/assets/javascripts/boards/components/sidebar/board_sidebar_due_date.vue
+++ b/app/assets/javascripts/boards/components/sidebar/board_sidebar_due_date.vue
@@ -18,7 +18,7 @@ export default {
};
},
computed: {
- ...mapGetters({ issue: 'activeIssue' }),
+ ...mapGetters({ issue: 'activeIssue', projectPathForActiveIssue: 'projectPathForActiveIssue' }),
hasDueDate() {
return this.issue.dueDate != null;
},
@@ -36,10 +36,6 @@ export default {
return dateInWords(this.parsedDueDate, true);
},
- projectPath() {
- const referencePath = this.issue.referencePath || '';
- return referencePath.slice(0, referencePath.indexOf('#'));
- },
},
methods: {
...mapActions(['setActiveIssueDueDate']),
@@ -53,7 +49,7 @@ export default {
try {
const dueDate = date ? formatDate(date, 'yyyy-mm-dd') : null;
- await this.setActiveIssueDueDate({ dueDate, projectPath: this.projectPath });
+ await this.setActiveIssueDueDate({ dueDate, projectPath: this.projectPathForActiveIssue });
} catch (e) {
createFlash({ message: this.$options.i18n.updateDueDateError });
} finally {
diff --git a/app/assets/javascripts/boards/components/sidebar/board_sidebar_labels_select.vue b/app/assets/javascripts/boards/components/sidebar/board_sidebar_labels_select.vue
index 31094939733..9d537a4ef2c 100644
--- a/app/assets/javascripts/boards/components/sidebar/board_sidebar_labels_select.vue
+++ b/app/assets/javascripts/boards/components/sidebar/board_sidebar_labels_select.vue
@@ -21,9 +21,9 @@ export default {
},
inject: ['labelsFetchPath', 'labelsManagePath', 'labelsFilterBasePath'],
computed: {
- ...mapGetters({ issue: 'activeIssue' }),
+ ...mapGetters(['activeIssue', 'projectPathForActiveIssue']),
selectedLabels() {
- const { labels = [] } = this.issue;
+ const { labels = [] } = this.activeIssue;
return labels.map(label => ({
...label,
@@ -31,17 +31,13 @@ export default {
}));
},
issueLabels() {
- const { labels = [] } = this.issue;
+ const { labels = [] } = this.activeIssue;
return labels.map(label => ({
...label,
scoped: isScopedLabel(label),
}));
},
- projectPath() {
- const { referencePath = '' } = this.issue;
- return referencePath.slice(0, referencePath.indexOf('#'));
- },
},
methods: {
...mapActions(['setActiveIssueLabels']),
@@ -55,7 +51,7 @@ export default {
.filter(label => !payload.find(selected => selected.id === label.id))
.map(label => label.id);
- const input = { addLabelIds, removeLabelIds, projectPath: this.projectPath };
+ const input = { addLabelIds, removeLabelIds, projectPath: this.projectPathForActiveIssue };
await this.setActiveIssueLabels(input);
} catch (e) {
createFlash({ message: __('An error occurred while updating labels.') });
@@ -68,7 +64,7 @@ export default {
try {
const removeLabelIds = [getIdFromGraphQLId(id)];
- const input = { removeLabelIds, projectPath: this.projectPath };
+ const input = { removeLabelIds, projectPath: this.projectPathForActiveIssue };
await this.setActiveIssueLabels(input);
} catch (e) {
createFlash({ message: __('An error occurred when removing the label.') });
diff --git a/app/assets/javascripts/boards/components/sidebar/board_sidebar_subscription.vue b/app/assets/javascripts/boards/components/sidebar/board_sidebar_subscription.vue
new file mode 100644
index 00000000000..ed069cea630
--- /dev/null
+++ b/app/assets/javascripts/boards/components/sidebar/board_sidebar_subscription.vue
@@ -0,0 +1,71 @@
+<script>
+import { mapGetters, mapActions } from 'vuex';
+import { GlToggle } from '@gitlab/ui';
+import createFlash from '~/flash';
+import { __, s__ } from '~/locale';
+
+export default {
+ i18n: {
+ header: {
+ title: __('Notifications'),
+ /* Any change to subscribeDisabledDescription
+ must be reflected in app/helpers/notifications_helper.rb */
+ subscribeDisabledDescription: __(
+ 'Notifications have been disabled by the project or group owner',
+ ),
+ },
+ updateSubscribedErrorMessage: s__(
+ 'IssueBoards|An error occurred while setting notifications status.',
+ ),
+ },
+ components: {
+ GlToggle,
+ },
+ data() {
+ return {
+ loading: false,
+ };
+ },
+ computed: {
+ ...mapGetters(['activeIssue', 'projectPathForActiveIssue']),
+ notificationText() {
+ return this.activeIssue.emailsDisabled
+ ? this.$options.i18n.header.subscribeDisabledDescription
+ : this.$options.i18n.header.title;
+ },
+ },
+ methods: {
+ ...mapActions(['setActiveIssueSubscribed']),
+ async handleToggleSubscription() {
+ this.loading = true;
+
+ try {
+ await this.setActiveIssueSubscribed({
+ subscribed: !this.activeIssue.subscribed,
+ projectPath: this.projectPathForActiveIssue,
+ });
+ } catch (error) {
+ createFlash({ message: this.$options.i18n.updateSubscribedErrorMessage });
+ } finally {
+ this.loading = false;
+ }
+ },
+ },
+};
+</script>
+
+<template>
+ <div
+ class="gl-display-flex gl-align-items-center gl-justify-content-space-between"
+ data-testid="sidebar-notifications"
+ >
+ <span data-testid="notification-header-text"> {{ notificationText }} </span>
+ <gl-toggle
+ v-if="!activeIssue.emailsDisabled"
+ :value="activeIssue.subscribed"
+ :is-loading="loading"
+ data-testid="notification-subscribe-toggle"
+ @change="handleToggleSubscription"
+ />
+ </div>
+</template>
diff --git a/app/assets/javascripts/boards/graphql/mutations/issue_set_subscription.mutation.graphql b/app/assets/javascripts/boards/graphql/mutations/issue_set_subscription.mutation.graphql
new file mode 100644
index 00000000000..1f383245ac2
--- /dev/null
+++ b/app/assets/javascripts/boards/graphql/mutations/issue_set_subscription.mutation.graphql
@@ -0,0 +1,8 @@
+mutation issueSetSubscription($input: IssueSetSubscriptionInput!) {
+ issueSetSubscription(input: $input) {
+ issue {
+ subscribed
+ }
+ errors
+ }
+}
diff --git a/app/assets/javascripts/boards/stores/actions.js b/app/assets/javascripts/boards/stores/actions.js
index 2552a3a4113..dd950a45076 100644
--- a/app/assets/javascripts/boards/stores/actions.js
+++ b/app/assets/javascripts/boards/stores/actions.js
@@ -24,6 +24,7 @@ import destroyBoardListMutation from '../queries/board_list_destroy.mutation.gra
import issueCreateMutation from '../queries/issue_create.mutation.graphql';
import issueSetLabels from '../queries/issue_set_labels.mutation.graphql';
import issueSetDueDate from '../queries/issue_set_due_date.mutation.graphql';
+import issueSetSubscriptionMutation from '../graphql/mutations/issue_set_subscription.mutation.graphql';
const notImplemented = () => {
/* eslint-disable-next-line @gitlab/require-i18n-strings */
@@ -423,6 +424,29 @@ export default {
});
},
+ setActiveIssueSubscribed: async ({ commit, getters }, input) => {
+ const { data } = await gqlClient.mutate({
+ mutation: issueSetSubscriptionMutation,
+ variables: {
+ input: {
+ iid: String(getters.activeIssue.iid),
+ projectPath: input.projectPath,
+ subscribedState: input.subscribed,
+ },
+ },
+ });
+
+ if (data.issueSetSubscription?.errors?.length > 0) {
+ throw new Error(data.issueSetSubscription.errors);
+ }
+
+ commit(types.UPDATE_ISSUE_BY_ID, {
+ issueId: getters.activeIssue.id,
+ prop: 'subscribed',
+ value: data.issueSetSubscription.issue.subscribed,
+ });
+ },
+
fetchBacklog: () => {
notImplemented();
},
diff --git a/app/assets/javascripts/boards/stores/getters.js b/app/assets/javascripts/boards/stores/getters.js
index f717b4101ab..cd28b4a0ff7 100644
--- a/app/assets/javascripts/boards/stores/getters.js
+++ b/app/assets/javascripts/boards/stores/getters.js
@@ -24,6 +24,11 @@ export default {
return state.issues[state.activeId] || {};
},
+ projectPathForActiveIssue: (_, getters) => {
+ const referencePath = getters.activeIssue.referencePath || '';
+ return referencePath.slice(0, referencePath.indexOf('#'));
+ },
+
getListByLabelId: state => labelId => {
return find(state.boardLists, l => l.label?.id === labelId);
},