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>2021-08-19 12:08:42 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-08-19 12:08:42 +0300
commitb76ae638462ab0f673e5915986070518dd3f9ad3 (patch)
treebdab0533383b52873be0ec0eb4d3c66598ff8b91 /app/assets/javascripts/design_management
parent434373eabe7b4be9593d18a585fb763f1e5f1a6f (diff)
Add latest changes from gitlab-org/gitlab@14-2-stable-eev14.2.0-rc42
Diffstat (limited to 'app/assets/javascripts/design_management')
-rw-r--r--app/assets/javascripts/design_management/components/design_notes/design_discussion.vue20
-rw-r--r--app/assets/javascripts/design_management/components/image.vue14
-rw-r--r--app/assets/javascripts/design_management/components/upload/design_version_dropdown.vue30
-rw-r--r--app/assets/javascripts/design_management/graphql.js8
-rw-r--r--app/assets/javascripts/design_management/graphql/fragmentTypes.json1
-rw-r--r--app/assets/javascripts/design_management/graphql/fragments/design_todo_item.fragment.graphql11
-rw-r--r--app/assets/javascripts/design_management/graphql/mutations/create_image_diff_note.mutation.graphql6
-rw-r--r--app/assets/javascripts/design_management/graphql/mutations/toggle_resolve_discussion.mutation.graphql6
-rw-r--r--app/assets/javascripts/design_management/index.js12
-rw-r--r--app/assets/javascripts/design_management/pages/design/index.vue20
10 files changed, 120 insertions, 8 deletions
diff --git a/app/assets/javascripts/design_management/components/design_notes/design_discussion.vue b/app/assets/javascripts/design_management/components/design_notes/design_discussion.vue
index 78ba586ce37..813f87452d8 100644
--- a/app/assets/javascripts/design_management/components/design_notes/design_discussion.vue
+++ b/app/assets/javascripts/design_management/components/design_notes/design_discussion.vue
@@ -4,13 +4,16 @@ import { ApolloMutation } from 'vue-apollo';
import createFlash from '~/flash';
import { s__ } from '~/locale';
import ReplyPlaceholder from '~/notes/components/discussion_reply_placeholder.vue';
+import { updateGlobalTodoCount } from '~/vue_shared/components/sidebar/todo_toggle/utils';
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import { ACTIVE_DISCUSSION_SOURCE_TYPES } from '../../constants';
import createNoteMutation from '../../graphql/mutations/create_note.mutation.graphql';
import toggleResolveDiscussionMutation from '../../graphql/mutations/toggle_resolve_discussion.mutation.graphql';
import activeDiscussionQuery from '../../graphql/queries/active_discussion.query.graphql';
+import getDesignQuery from '../../graphql/queries/get_design.query.graphql';
import allVersionsMixin from '../../mixins/all_versions';
import { hasErrors } from '../../utils/cache_update';
+import { extractDesign } from '../../utils/design_management_utils';
import { ADD_DISCUSSION_COMMENT_ERROR } from '../../utils/error_messages';
import DesignNote from './design_note.vue';
import DesignReplyForm from './design_reply_form.vue';
@@ -161,6 +164,19 @@ export default {
},
toggleResolvedStatus() {
this.isResolving = true;
+
+ /**
+ * Get previous todo count
+ */
+ const { defaultClient: client } = this.$apollo.provider.clients;
+ const sourceData = client.readQuery({
+ query: getDesignQuery,
+ variables: this.designVariables,
+ });
+
+ const design = extractDesign(sourceData);
+ const prevTodoCount = design.currentUserTodos?.nodes?.length || 0;
+
this.$apollo
.mutate({
mutation: toggleResolveDiscussionMutation,
@@ -170,6 +186,10 @@ export default {
if (data.errors?.length > 0) {
this.$emit('resolve-discussion-error', data.errors[0]);
}
+ const newTodoCount =
+ data?.discussionToggleResolve?.discussion?.noteable?.currentUserTodos?.nodes?.length ||
+ 0;
+ updateGlobalTodoCount(newTodoCount - prevTodoCount);
})
.catch((err) => {
this.$emit('resolve-discussion-error', err);
diff --git a/app/assets/javascripts/design_management/components/image.vue b/app/assets/javascripts/design_management/components/image.vue
index e64ee4a5a34..8ab94cd2c4b 100644
--- a/app/assets/javascripts/design_management/components/image.vue
+++ b/app/assets/javascripts/design_management/components/image.vue
@@ -1,6 +1,8 @@
<script>
import { GlIcon } from '@gitlab/ui';
import { throttle } from 'lodash';
+import { DESIGN_MARK_APP_START, DESIGN_MAIN_IMAGE_OUTPUT } from '~/performance/constants';
+import { performanceMarkAndMeasure } from '~/performance/utils';
export default {
components: {
@@ -39,7 +41,9 @@ export default {
window.removeEventListener('resize', this.resizeThrottled, false);
},
mounted() {
- this.onImgLoad();
+ if (!this.image) {
+ this.onImgLoad();
+ }
this.resizeThrottled = throttle(() => {
// NOTE: if imageStyle is set, then baseImageSize
@@ -53,6 +57,14 @@ export default {
methods: {
onImgLoad() {
requestIdleCallback(this.setBaseImageSize, { timeout: 1000 });
+ performanceMarkAndMeasure({
+ measures: [
+ {
+ name: DESIGN_MAIN_IMAGE_OUTPUT,
+ start: DESIGN_MARK_APP_START,
+ },
+ ],
+ });
},
onImgError() {
this.imageError = true;
diff --git a/app/assets/javascripts/design_management/components/upload/design_version_dropdown.vue b/app/assets/javascripts/design_management/components/upload/design_version_dropdown.vue
index 750f16bbe57..816d7ac7abf 100644
--- a/app/assets/javascripts/design_management/components/upload/design_version_dropdown.vue
+++ b/app/assets/javascripts/design_management/components/upload/design_version_dropdown.vue
@@ -1,6 +1,8 @@
<script>
import { GlDropdown, GlDropdownItem, GlSprintf } from '@gitlab/ui';
+import defaultAvatarUrl from 'images/no_avatar.png';
import { __, sprintf } from '~/locale';
+import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue';
import allVersionsMixin from '../../mixins/all_versions';
import { findVersionId } from '../../utils/design_management_utils';
@@ -9,6 +11,7 @@ export default {
GlDropdown,
GlDropdownItem,
GlSprintf,
+ TimeAgo,
},
mixins: [allVersionsMixin],
computed: {
@@ -58,6 +61,9 @@ export default {
}
return __('Version %{versionNumber}');
},
+ getAvatarUrl(version) {
+ return version?.author?.avatarUrl || defaultAvatarUrl;
+ },
},
};
</script>
@@ -68,14 +74,28 @@ export default {
v-for="(version, index) in allVersions"
:key="version.id"
:is-check-item="true"
+ :is-check-centered="true"
:is-checked="findVersionId(version.id) === currentVersionId"
+ :avatar-url="getAvatarUrl(version)"
@click="routeToVersion(version.id)"
>
- <gl-sprintf :message="versionText(version.id)">
- <template #versionNumber>
- {{ allVersions.length - index }}
- </template>
- </gl-sprintf>
+ <strong>
+ <gl-sprintf :message="versionText(version.id)">
+ <template #versionNumber>
+ {{ allVersions.length - index }}
+ </template>
+ </gl-sprintf>
+ </strong>
+
+ <div v-if="version.author" class="gl-text-gray-600 gl-mt-1">
+ <div>{{ version.author.name }}</div>
+ <time-ago
+ v-if="version.createdAt"
+ class="text-1"
+ :time="version.createdAt"
+ tooltip-placement="bottom"
+ />
+ </div>
</gl-dropdown-item>
</gl-dropdown>
</template>
diff --git a/app/assets/javascripts/design_management/graphql.js b/app/assets/javascripts/design_management/graphql.js
index 9a0547ee9db..fa57537f74e 100644
--- a/app/assets/javascripts/design_management/graphql.js
+++ b/app/assets/javascripts/design_management/graphql.js
@@ -1,10 +1,11 @@
-import { defaultDataIdFromObject } from 'apollo-cache-inmemory';
+import { defaultDataIdFromObject, IntrospectionFragmentMatcher } from 'apollo-cache-inmemory';
import produce from 'immer';
import { uniqueId } from 'lodash';
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createDefaultClient from '~/lib/graphql';
import axios from '~/lib/utils/axios_utils';
+import introspectionQueryResultData from './graphql/fragmentTypes.json';
import activeDiscussionQuery from './graphql/queries/active_discussion.query.graphql';
import getDesignQuery from './graphql/queries/get_design.query.graphql';
import typeDefs from './graphql/typedefs.graphql';
@@ -12,6 +13,10 @@ import { addPendingTodoToStore } from './utils/cache_update';
import { extractTodoIdFromDeletePath, createPendingTodo } from './utils/design_management_utils';
import { CREATE_DESIGN_TODO_EXISTS_ERROR } from './utils/error_messages';
+const fragmentMatcher = new IntrospectionFragmentMatcher({
+ introspectionQueryResultData,
+});
+
Vue.use(VueApollo);
const resolvers = {
@@ -80,6 +85,7 @@ const defaultClient = createDefaultClient(
}
return defaultDataIdFromObject(object);
},
+ fragmentMatcher,
},
typeDefs,
assumeImmutableResults: true,
diff --git a/app/assets/javascripts/design_management/graphql/fragmentTypes.json b/app/assets/javascripts/design_management/graphql/fragmentTypes.json
new file mode 100644
index 00000000000..0953231ea4c
--- /dev/null
+++ b/app/assets/javascripts/design_management/graphql/fragmentTypes.json
@@ -0,0 +1 @@
+{"__schema":{"types":[{"kind":"INTERFACE","name":"User","possibleTypes":[{"name":"UserCore"}]},{"kind":"UNION","name":"NoteableType","possibleTypes":[{"name":"Design"},{"name":"Issue"},{"name":"MergeRequest"}]}]}}
diff --git a/app/assets/javascripts/design_management/graphql/fragments/design_todo_item.fragment.graphql b/app/assets/javascripts/design_management/graphql/fragments/design_todo_item.fragment.graphql
new file mode 100644
index 00000000000..3fe20705ce2
--- /dev/null
+++ b/app/assets/javascripts/design_management/graphql/fragments/design_todo_item.fragment.graphql
@@ -0,0 +1,11 @@
+fragment DesignTodoItem on Design {
+ id
+ image
+ __typename
+ currentUserTodos(state: pending) {
+ nodes {
+ id
+ __typename
+ }
+ }
+}
diff --git a/app/assets/javascripts/design_management/graphql/mutations/create_image_diff_note.mutation.graphql b/app/assets/javascripts/design_management/graphql/mutations/create_image_diff_note.mutation.graphql
index 0b8400ac040..41c3f56f477 100644
--- a/app/assets/javascripts/design_management/graphql/mutations/create_image_diff_note.mutation.graphql
+++ b/app/assets/javascripts/design_management/graphql/mutations/create_image_diff_note.mutation.graphql
@@ -1,4 +1,5 @@
#import "../fragments/design_note.fragment.graphql"
+#import "../fragments/design_todo_item.fragment.graphql"
mutation createImageDiffNote($input: CreateImageDiffNoteInput!) {
createImageDiffNote(input: $input) {
@@ -7,6 +8,11 @@ mutation createImageDiffNote($input: CreateImageDiffNoteInput!) {
discussion {
id
replyId
+ noteable {
+ ... on Design {
+ ...DesignTodoItem
+ }
+ }
notes {
nodes {
...DesignNote
diff --git a/app/assets/javascripts/design_management/graphql/mutations/toggle_resolve_discussion.mutation.graphql b/app/assets/javascripts/design_management/graphql/mutations/toggle_resolve_discussion.mutation.graphql
index 1157fc05d5f..124f12ef018 100644
--- a/app/assets/javascripts/design_management/graphql/mutations/toggle_resolve_discussion.mutation.graphql
+++ b/app/assets/javascripts/design_management/graphql/mutations/toggle_resolve_discussion.mutation.graphql
@@ -1,11 +1,17 @@
#import "../fragments/design_note.fragment.graphql"
#import "../fragments/discussion_resolved_status.fragment.graphql"
+#import "../fragments/design_todo_item.fragment.graphql"
mutation toggleResolveDiscussion($id: ID!, $resolve: Boolean!) {
discussionToggleResolve(input: { id: $id, resolve: $resolve }) {
discussion {
id
...ResolvedStatus
+ noteable {
+ ... on Design {
+ ...DesignTodoItem
+ }
+ }
notes {
nodes {
...DesignNote
diff --git a/app/assets/javascripts/design_management/index.js b/app/assets/javascripts/design_management/index.js
index aa9f377ef16..11666587265 100644
--- a/app/assets/javascripts/design_management/index.js
+++ b/app/assets/javascripts/design_management/index.js
@@ -1,4 +1,6 @@
import Vue from 'vue';
+import { DESIGN_MARK_APP_START, DESIGN_MEASURE_BEFORE_APP } from '~/performance/constants';
+import { performanceMarkAndMeasure } from '~/performance/utils';
import App from './components/app.vue';
import apolloProvider from './graphql';
import activeDiscussionQuery from './graphql/queries/active_discussion.query.graphql';
@@ -28,6 +30,16 @@ export default () => {
projectPath,
issueIid,
},
+ mounted() {
+ performanceMarkAndMeasure({
+ mark: DESIGN_MARK_APP_START,
+ measures: [
+ {
+ name: DESIGN_MEASURE_BEFORE_APP,
+ },
+ ],
+ });
+ },
render(createElement) {
return createElement(App);
},
diff --git a/app/assets/javascripts/design_management/pages/design/index.vue b/app/assets/javascripts/design_management/pages/design/index.vue
index 19bfa123487..48ee7068809 100644
--- a/app/assets/javascripts/design_management/pages/design/index.vue
+++ b/app/assets/javascripts/design_management/pages/design/index.vue
@@ -1,10 +1,12 @@
<script>
import { GlLoadingIcon, GlAlert } from '@gitlab/ui';
+import { isNull } from 'lodash';
import Mousetrap from 'mousetrap';
import { ApolloMutation } from 'vue-apollo';
import { keysFor, ISSUE_CLOSE_DESIGN } from '~/behaviors/shortcuts/keybindings';
import createFlash from '~/flash';
import { fetchPolicies } from '~/lib/graphql';
+import { updateGlobalTodoCount } from '~/vue_shared/components/sidebar/todo_toggle/utils';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import DesignDestroyer from '../../components/design_destroyer.vue';
import DesignReplyForm from '../../components/design_notes/design_reply_form.vue';
@@ -93,6 +95,7 @@ export default {
errorMessage: '',
scale: DEFAULT_SCALE,
resolvedDiscussionsExpanded: false,
+ prevCurrentUserTodos: null,
};
},
apollo: {
@@ -163,6 +166,13 @@ export default {
resolvedDiscussions() {
return this.discussions.filter((discussion) => discussion.resolved);
},
+ currentUserTodos() {
+ if (!this.design || !this.design.currentUserTodos) {
+ return null;
+ }
+
+ return this.design.currentUserTodos?.nodes?.length;
+ },
},
watch: {
resolvedDiscussions(val) {
@@ -170,6 +180,9 @@ export default {
this.resolvedDiscussionsExpanded = false;
}
},
+ currentUserTodos(_, prevCurrentUserTodos) {
+ this.prevCurrentUserTodos = prevCurrentUserTodos;
+ },
},
mounted() {
Mousetrap.bind(keysFor(ISSUE_CLOSE_DESIGN), this.closeDesign);
@@ -272,9 +285,14 @@ export default {
this.$refs.newDiscussionForm.focusInput();
}
},
- closeCommentForm() {
+ closeCommentForm(data) {
this.comment = '';
this.annotationCoordinates = null;
+
+ if (data?.data && !isNull(this.prevCurrentUserTodos)) {
+ updateGlobalTodoCount(this.currentUserTodos - this.prevCurrentUserTodos);
+ this.prevCurrentUserTodos = this.currentUserTodos;
+ }
},
closeDesign() {
this.$router.push({