diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION index ad340ae0947..8ea542caa2e 100644 --- a/GITALY_SERVER_VERSION +++ b/GITALY_SERVER_VERSION @@ -1 +1 @@ -fa974a4ab21aa6acc4c3a00456265248a4d70703 +9cde939eef5182b062f9aa04a3a3f78d8264af4b diff --git a/app/assets/javascripts/alerts_settings/components/alerts_settings_form_new.vue b/app/assets/javascripts/alerts_settings/components/alerts_settings_form_new.vue index a08100f3938..81ee86fe797 100644 --- a/app/assets/javascripts/alerts_settings/components/alerts_settings_form_new.vue +++ b/app/assets/javascripts/alerts_settings/components/alerts_settings_form_new.vue @@ -17,6 +17,7 @@ import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import { s__ } from '~/locale'; import ClipboardButton from '~/vue_shared/components/clipboard_button.vue'; import AlertSettingsFormHelpBlock from './alert_settings_form_help_block.vue'; +import service from '../services'; import { integrationTypesNew, JSON_VALIDATE_DELAY, @@ -89,7 +90,7 @@ export default { MappingBuilder, }, directives: { - 'gl-modal': GlModalDirective, + GlModal: GlModalDirective, }, inject: { generic: { @@ -150,6 +151,13 @@ export default { apiUrl: this.currentIntegration?.apiUrl || '', }; }, + testAlertPayload() { + return { + data: this.integrationTestPayload.json, + endpoint: this.integrationForm.url, + token: this.integrationForm.token, + }; + }, }, watch: { currentIntegration(val) { @@ -170,8 +178,14 @@ export default { } }, submitWithTestPayload() { - // TODO: Test payload before saving via GraphQL - this.submit(); + return service + .updateTestAlert(this.testAlertPayload) + .then(() => { + this.submit(); + }) + .catch(() => { + this.$emit('test-payload-failure'); + }); }, submit() { const { name, apiUrl } = this.integrationForm; @@ -359,7 +373,6 @@ export default { {{ __('Cancel') }} @@ -266,6 +270,7 @@ export default { @update-integration="updateIntegration" @reset-token="resetToken" @clear-current-integration="clearCurrentIntegration" + @test-payload-failure="testPayloadFailure" /> diff --git a/app/assets/javascripts/alerts_settings/services/index.js b/app/assets/javascripts/alerts_settings/services/index.js index c49992d4f57..1835d6b46aa 100644 --- a/app/assets/javascripts/alerts_settings/services/index.js +++ b/app/assets/javascripts/alerts_settings/services/index.js @@ -2,6 +2,7 @@ import axios from '~/lib/utils/axios_utils'; export default { + // TODO: All this code save updateTestAlert will be deleted as part of: https://gitlab.com/gitlab-org/gitlab/-/issues/255501 updateGenericKey({ endpoint, params }) { return axios.put(endpoint, params); }, @@ -25,11 +26,11 @@ export default { }, }); }, - updateTestAlert({ endpoint, data, authKey }) { + updateTestAlert({ endpoint, data, token }) { return axios.post(endpoint, data, { headers: { 'Content-Type': 'application/json', - Authorization: `Bearer ${authKey}`, + Authorization: `Bearer ${token}`, }, }); }, diff --git a/app/assets/javascripts/alerts_settings/utils/error_messages.js b/app/assets/javascripts/alerts_settings/utils/error_messages.js index 7df5d444a53..979d1ca3ccc 100644 --- a/app/assets/javascripts/alerts_settings/utils/error_messages.js +++ b/app/assets/javascripts/alerts_settings/utils/error_messages.js @@ -15,3 +15,7 @@ export const UPDATE_INTEGRATION_ERROR = s__( export const RESET_INTEGRATION_TOKEN_ERROR = s__( 'AlertsIntegrations|The integration token could not be reset. Please try again.', ); + +export const INTEGRATION_PAYLOAD_TEST_ERROR = s__( + 'AlertsIntegrations|Integration payload is invalid. You can still save your changes.', +); diff --git a/app/assets/javascripts/batch_comments/components/inline_draft_comment_row.vue b/app/assets/javascripts/batch_comments/components/inline_draft_comment_row.vue deleted file mode 100644 index 385725cd109..00000000000 --- a/app/assets/javascripts/batch_comments/components/inline_draft_comment_row.vue +++ /dev/null @@ -1,32 +0,0 @@ - - - diff --git a/app/assets/javascripts/batch_comments/components/parallel_draft_comment_row.vue b/app/assets/javascripts/batch_comments/components/parallel_draft_comment_row.vue deleted file mode 100644 index b0916623cd2..00000000000 --- a/app/assets/javascripts/batch_comments/components/parallel_draft_comment_row.vue +++ /dev/null @@ -1,49 +0,0 @@ - - - diff --git a/app/assets/javascripts/boards/components/board_assignee_dropdown.vue b/app/assets/javascripts/boards/components/board_assignee_dropdown.vue index b2c3b6aa8ab..2245c0d0f44 100644 --- a/app/assets/javascripts/boards/components/board_assignee_dropdown.vue +++ b/app/assets/javascripts/boards/components/board_assignee_dropdown.vue @@ -4,7 +4,7 @@ import { GlDropdownItem, GlDropdownDivider, GlAvatarLabeled, GlAvatarLink } from import { __, n__ } from '~/locale'; import IssuableAssignees from '~/sidebar/components/assignees/issuable_assignees.vue'; import BoardEditableItem from '~/boards/components/sidebar/board_editable_item.vue'; -import AssigneesDropdown from '~/vue_shared/components/sidebar/assignees_dropdown.vue'; +import MultiSelectDropdown from '~/vue_shared/components/sidebar/multiselect_dropdown.vue'; import getIssueParticipants from '~/vue_shared/components/sidebar/queries/getIssueParticipants.query.graphql'; export default { @@ -17,7 +17,7 @@ export default { components: { BoardEditableItem, IssuableAssignees, - AssigneesDropdown, + MultiSelectDropdown, GlDropdownItem, GlDropdownDivider, GlAvatarLabeled, @@ -92,7 +92,7 @@ export default { - + diff --git a/app/assets/javascripts/design_management/components/design_overlay.vue b/app/assets/javascripts/design_management/components/design_overlay.vue index 88f3ce0b8ea..3c2ce693bc0 100644 --- a/app/assets/javascripts/design_management/components/design_overlay.vue +++ b/app/assets/javascripts/design_management/components/design_overlay.vue @@ -112,9 +112,9 @@ export default { }, canMoveNote(note) { const { userPermissions } = note; - const { adminNote } = userPermissions || {}; + const { repositionNote } = userPermissions || {}; - return Boolean(adminNote); + return Boolean(repositionNote); }, isPositionInOverlay(position) { const { top, left } = this.getNoteRelativePosition(position); diff --git a/app/assets/javascripts/design_management/graphql/fragments/note_permissions.fragment.graphql b/app/assets/javascripts/design_management/graphql/fragments/note_permissions.fragment.graphql index c243e39f3d3..e599ab19c2d 100644 --- a/app/assets/javascripts/design_management/graphql/fragments/note_permissions.fragment.graphql +++ b/app/assets/javascripts/design_management/graphql/fragments/note_permissions.fragment.graphql @@ -1,3 +1,4 @@ fragment DesignNotePermissions on NotePermissions { adminNote + repositionNote } diff --git a/app/assets/javascripts/design_management/graphql/mutations/reposition_image_diff_note.mutation.graphql b/app/assets/javascripts/design_management/graphql/mutations/reposition_image_diff_note.mutation.graphql new file mode 100644 index 00000000000..78fbcf1c3c7 --- /dev/null +++ b/app/assets/javascripts/design_management/graphql/mutations/reposition_image_diff_note.mutation.graphql @@ -0,0 +1,10 @@ +#import "../fragments/design_note.fragment.graphql" + +mutation repositionImageDiffNote($input: RepositionImageDiffNoteInput!) { + repositionImageDiffNote(input: $input) { + errors + note { + ...DesignNote + } + } +} diff --git a/app/assets/javascripts/design_management/graphql/mutations/update_image_diff_note.mutation.graphql b/app/assets/javascripts/design_management/graphql/mutations/update_image_diff_note.mutation.graphql deleted file mode 100644 index 5562ca9d89f..00000000000 --- a/app/assets/javascripts/design_management/graphql/mutations/update_image_diff_note.mutation.graphql +++ /dev/null @@ -1,10 +0,0 @@ -#import "../fragments/design_note.fragment.graphql" - -mutation updateImageDiffNote($input: UpdateImageDiffNoteInput!) { - updateImageDiffNote(input: $input) { - errors - note { - ...DesignNote - } - } -} diff --git a/app/assets/javascripts/design_management/pages/design/index.vue b/app/assets/javascripts/design_management/pages/design/index.vue index f410a976676..d1bbb5239d0 100644 --- a/app/assets/javascripts/design_management/pages/design/index.vue +++ b/app/assets/javascripts/design_management/pages/design/index.vue @@ -13,19 +13,19 @@ import DesignReplyForm from '../../components/design_notes/design_reply_form.vue import DesignSidebar from '../../components/design_sidebar.vue'; import getDesignQuery from '../../graphql/queries/get_design.query.graphql'; import createImageDiffNoteMutation from '../../graphql/mutations/create_image_diff_note.mutation.graphql'; -import updateImageDiffNoteMutation from '../../graphql/mutations/update_image_diff_note.mutation.graphql'; +import repositionImageDiffNoteMutation from '../../graphql/mutations/reposition_image_diff_note.mutation.graphql'; import updateActiveDiscussionMutation from '../../graphql/mutations/update_active_discussion.mutation.graphql'; import { extractDiscussions, extractDesign, - updateImageDiffNoteOptimisticResponse, + repositionImageDiffNoteOptimisticResponse, toDiffNoteGid, extractDesignNoteId, getPageLayoutElement, } from '../../utils/design_management_utils'; import { updateStoreAfterAddImageDiffNote, - updateStoreAfterUpdateImageDiffNote, + updateStoreAfterRepositionImageDiffNote, } from '../../utils/cache_update'; import { ADD_DISCUSSION_COMMENT_ERROR, @@ -182,12 +182,12 @@ export default { updateImageDiffNoteInStore( store, { - data: { updateImageDiffNote }, + data: { repositionImageDiffNote }, }, ) { - return updateStoreAfterUpdateImageDiffNote( + return updateStoreAfterRepositionImageDiffNote( store, - updateImageDiffNote, + repositionImageDiffNote, getDesignQuery, this.designVariables, ); @@ -199,7 +199,7 @@ export default { ); const mutationPayload = { - optimisticResponse: updateImageDiffNoteOptimisticResponse(note, { + optimisticResponse: repositionImageDiffNoteOptimisticResponse(note, { position, }), variables: { @@ -208,7 +208,7 @@ export default { position, }, }, - mutation: updateImageDiffNoteMutation, + mutation: repositionImageDiffNoteMutation, update: this.updateImageDiffNoteInStore, }; diff --git a/app/assets/javascripts/design_management/utils/cache_update.js b/app/assets/javascripts/design_management/utils/cache_update.js index ac4763853ef..5bd0288d037 100644 --- a/app/assets/javascripts/design_management/utils/cache_update.js +++ b/app/assets/javascripts/design_management/utils/cache_update.js @@ -101,7 +101,7 @@ const addImageDiffNoteToStore = (store, createImageDiffNote, query, variables) = }); }; -const updateImageDiffNoteInStore = (store, updateImageDiffNote, query, variables) => { +const updateImageDiffNoteInStore = (store, repositionImageDiffNote, query, variables) => { const sourceData = store.readQuery({ query, variables, @@ -111,12 +111,12 @@ const updateImageDiffNoteInStore = (store, updateImageDiffNote, query, variables const design = extractDesign(draftData); const discussion = extractCurrentDiscussion( design.discussions, - updateImageDiffNote.note.discussion.id, + repositionImageDiffNote.note.discussion.id, ); discussion.notes = { ...discussion.notes, - nodes: [updateImageDiffNote.note, ...discussion.notes.nodes.slice(1)], + nodes: [repositionImageDiffNote.note, ...discussion.notes.nodes.slice(1)], }; }); @@ -268,7 +268,7 @@ export const updateStoreAfterAddImageDiffNote = (store, data, query, queryVariab } }; -export const updateStoreAfterUpdateImageDiffNote = (store, data, query, queryVariables) => { +export const updateStoreAfterRepositionImageDiffNote = (store, data, query, queryVariables) => { if (hasErrors(data)) { onError(data, UPDATE_IMAGE_DIFF_NOTE_ERROR); } else { diff --git a/app/assets/javascripts/design_management/utils/design_management_utils.js b/app/assets/javascripts/design_management/utils/design_management_utils.js index 687e793d3df..a905230811c 100644 --- a/app/assets/javascripts/design_management/utils/design_management_utils.js +++ b/app/assets/javascripts/design_management/utils/design_management_utils.js @@ -107,12 +107,12 @@ export const designUploadOptimisticResponse = files => { * @param {Object} note * @param {Object} position */ -export const updateImageDiffNoteOptimisticResponse = (note, { position }) => ({ +export const repositionImageDiffNoteOptimisticResponse = (note, { position }) => ({ // False positive i18n lint: https://gitlab.com/gitlab-org/frontend/eslint-plugin-i18n/issues/26 // eslint-disable-next-line @gitlab/require-i18n-strings __typename: 'Mutation', - updateImageDiffNote: { - __typename: 'UpdateImageDiffNotePayload', + repositionImageDiffNote: { + __typename: 'RepositionImageDiffNotePayload', note: { ...note, position: { diff --git a/app/assets/javascripts/diffs/components/diff_comment_cell.vue b/app/assets/javascripts/diffs/components/diff_comment_cell.vue new file mode 100644 index 00000000000..4b0b603f5a5 --- /dev/null +++ b/app/assets/javascripts/diffs/components/diff_comment_cell.vue @@ -0,0 +1,69 @@ + + + diff --git a/app/assets/javascripts/diffs/components/diff_content.vue b/app/assets/javascripts/diffs/components/diff_content.vue index e68260b3e62..401064fb18f 100644 --- a/app/assets/javascripts/diffs/components/diff_content.vue +++ b/app/assets/javascripts/diffs/components/diff_content.vue @@ -10,6 +10,7 @@ import NoPreviewViewer from '~/vue_shared/components/diff_viewer/viewers/no_prev import DiffFileDrafts from '~/batch_comments/components/diff_file_drafts.vue'; import InlineDiffView from './inline_diff_view.vue'; import ParallelDiffView from './parallel_diff_view.vue'; +import DiffView from './diff_view.vue'; import userAvatarLink from '../../vue_shared/components/user_avatar/user_avatar_link.vue'; import NoteForm from '../../notes/components/note_form.vue'; import ImageDiffOverlay from './image_diff_overlay.vue'; @@ -18,12 +19,14 @@ import eventHub from '../../notes/event_hub'; import { IMAGE_DIFF_POSITION_TYPE } from '../constants'; import { getDiffMode } from '../store/utils'; import { diffViewerModes } from '~/ide/constants'; +import { mapInline, mapParallel } from './diff_row_utils'; export default { components: { GlLoadingIcon, InlineDiffView, ParallelDiffView, + DiffView, DiffViewer, NoteForm, DiffDiscussions, @@ -83,6 +86,19 @@ export default { author() { return this.getUserData; }, + mappedLines() { + if (this.glFeatures.unifiedDiffLines && this.glFeatures.unifiedDiffComponents) { + return this.diffLines(this.diffFile, true).map(mapParallel(this)) || []; + } + + // TODO: Everything below this line can be deleted when unifiedDiffComponents FF is removed + if (this.isInlineView) { + return this.diffFile.highlighted_diff_lines.map(mapInline(this)); + } + return this.glFeatures.unifiedDiffLines + ? this.diffLines(this.diffFile).map(mapParallel(this)) + : this.diffFile.parallel_diff_lines.map(mapParallel(this)) || []; + }, }, updated() { this.$nextTick(() => { @@ -113,19 +129,28 @@ export default {