diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-05-17 09:10:09 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-05-17 09:10:09 +0000 |
commit | eeb25534bae1021f5b7940138ee56dea8fc79949 (patch) | |
tree | 26cf3d6a4ac582ed3d0d3a20b82a200da580f1e3 /app/assets | |
parent | 75621c94b5dbe233edd72c3d8cc602fed25e84d2 (diff) | |
download | gitlab-ce-eeb25534bae1021f5b7940138ee56dea8fc79949.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets')
16 files changed, 158 insertions, 108 deletions
diff --git a/app/assets/javascripts/boards/components/board_content.vue b/app/assets/javascripts/boards/components/board_content.vue index 8304dfef527..9416cbf1884 100644 --- a/app/assets/javascripts/boards/components/board_content.vue +++ b/app/assets/javascripts/boards/components/board_content.vue @@ -130,7 +130,7 @@ export default { :list="list" :filters="filterParams" :data-draggable-item-type="$options.draggableItemTypes.list" - :class="{ 'gl-xs-display-none!': addColumnFormVisible }" + :class="{ 'gl-display-none! gl-sm-display-inline-block!': addColumnFormVisible }" @setActiveList="$emit('setActiveList', $event)" /> diff --git a/app/assets/javascripts/graphql_shared/issuable_client.js b/app/assets/javascripts/graphql_shared/issuable_client.js index d0b0a485fe6..706bfc9bdac 100644 --- a/app/assets/javascripts/graphql_shared/issuable_client.js +++ b/app/assets/javascripts/graphql_shared/issuable_client.js @@ -47,6 +47,16 @@ export const config = { }, }, }, + DescriptionVersion: { + fields: { + startVersionId: { + read() { + // we need to set this when fetching the diff in the last 10 mins , the starting diff will be the very first one , so need to save it + return ''; + }, + }, + }, + }, WorkItem: { fields: { // widgets policy because otherwise the subscriptions invalidate the cache diff --git a/app/assets/javascripts/packages_and_registries/settings/project/components/packages_cleanup_policy_form.vue b/app/assets/javascripts/packages_and_registries/settings/project/components/packages_cleanup_policy_form.vue index f95ec4336dc..80df8ef81e6 100644 --- a/app/assets/javascripts/packages_and_registries/settings/project/components/packages_cleanup_policy_form.vue +++ b/app/assets/javascripts/packages_and_registries/settings/project/components/packages_cleanup_policy_form.vue @@ -139,7 +139,7 @@ export default { :form-options="$options.formOptions.keepNDuplicatedPackageFiles" :label="$options.i18n.KEEP_N_DUPLICATED_PACKAGE_FILES_LABEL" :description="$options.i18n.KEEP_N_DUPLICATED_PACKAGE_FILES_DESCRIPTION" - dropdown-class="gl-md-max-w-50p gl-sm-pr-5" + dropdown-class="gl-md-max-w-50p" name="keep-n-duplicated-package-files" data-testid="keep-n-duplicated-package-files-dropdown" @input="onModelChange($event, 'keepNDuplicatedPackageFiles')" diff --git a/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue b/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue index 64c363dd721..031910b1cdb 100644 --- a/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue +++ b/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue @@ -552,7 +552,7 @@ export default { <template> <div> <div - class="project-visibility-setting gl-border-1 gl-border-solid gl-border-gray-100 gl-py-3 gl-px-7 gl-sm-pr-5 gl-sm-pl-5" + class="project-visibility-setting gl-border-1 gl-border-solid gl-border-gray-100 gl-py-3 gl-px-5" > <project-setting-row ref="project-visibility-settings" @@ -647,7 +647,7 @@ export default { </div> <div :class="{ 'highlight-changes': highlightChangesClass }" - class="gl-border-1 gl-border-solid gl-border-t-none gl-border-gray-100 gl-mb-5 gl-py-3 gl-px-7 gl-sm-pr-5 gl-sm-pl-5 gl-bg-gray-10" + class="gl-border-1 gl-border-solid gl-border-t-none gl-border-gray-100 gl-mb-5 gl-py-3 gl-px-5 gl-bg-gray-10" > <project-setting-row ref="issues-settings" @@ -693,7 +693,7 @@ export default { name="project[project_feature_attributes][repository_access_level]" /> </project-setting-row> - <div class="project-feature-setting-group gl-pl-7 gl-sm-pl-5"> + <div class="project-feature-setting-group gl-pl-5 gl-md-pl-7"> <project-setting-row ref="merge-request-settings" :label="$options.i18n.mergeRequestsLabel" @@ -875,7 +875,7 @@ export default { /> <div v-if="packageRegistryApiForEveryoneEnabledShown" - class="project-feature-setting-group gl-pl-7 gl-sm-pl-5 gl-my-3" + class="project-feature-setting-group gl-pl-5 gl-md-pl-7 gl-my-3" > <project-setting-row :label="$options.i18n.packageRegistryForEveryoneLabel" @@ -932,7 +932,7 @@ export default { </project-setting-row> <div v-if="!glFeatures.removeMonitorMetrics" - class="project-feature-setting-group gl-pl-7 gl-sm-pl-5" + class="project-feature-setting-group gl-pl-5 gl-md-pl-7" > <project-setting-row ref="metrics-visibility-settings" diff --git a/app/assets/javascripts/repository/components/fork_info.vue b/app/assets/javascripts/repository/components/fork_info.vue index 1da445a7906..e4a10784bd5 100644 --- a/app/assets/javascripts/repository/components/fork_info.vue +++ b/app/assets/javascripts/repository/components/fork_info.vue @@ -314,7 +314,7 @@ export default { > {{ $options.i18n.inaccessibleProject }} </div> - <div class="gl-display-flex gl-xs-display-none!"> + <div class="gl-display-none gl-sm-display-flex"> <gl-button v-if="hasCreateMrButton" class="gl-ml-4" diff --git a/app/assets/javascripts/work_items/components/notes/system_note.vue b/app/assets/javascripts/work_items/components/notes/system_note.vue index f8dfa1c7f01..534fbbe96ac 100644 --- a/app/assets/javascripts/work_items/components/notes/system_note.vue +++ b/app/assets/javascripts/work_items/components/notes/system_note.vue @@ -19,8 +19,7 @@ import { GlButton, GlSkeletonLoader, GlTooltipDirective, GlIcon } from '@gitlab/ import $ from 'jquery'; import { renderGFM } from '~/behaviors/markdown/render_gfm'; import SafeHtml from '~/vue_shared/directives/safe_html'; -import descriptionVersionHistoryMixin from 'ee_else_ce/notes/mixins/description_version_history'; -import axios from '~/lib/utils/axios_utils'; +import descriptionVersionHistoryMixin from 'ee_else_ce/work_items/mixins/description_version_history'; import { getLocationHash } from '~/lib/utils/url_utility'; import { getIdFromGraphQLId } from '~/graphql_shared/utils'; import { __ } from '~/locale'; @@ -28,8 +27,6 @@ import NoteHeader from '~/notes/components/note_header.vue'; import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import TimelineEntryItem from '~/vue_shared/components/notes/timeline_entry_item.vue'; -const MAX_VISIBLE_COMMIT_LIST_COUNT = 3; - export default { i18n: { deleteButtonLabel: __('Remove description history'), @@ -60,15 +57,13 @@ export default { showLines: false, loadingDiff: false, isLoadingDescriptionVersion: false, + descriptionVersions: {}, }; }, computed: { targetNoteHash() { return getLocationHash(); }, - descriptionVersions() { - return []; - }, noteAnchorId() { return `note_${this.noteId}`; }, @@ -78,42 +73,22 @@ export default { toggleIcon() { return this.expanded ? 'chevron-up' : 'chevron-down'; }, - // following 2 methods taken from code in `collapseLongCommitList` of notes.js: actionTextHtml() { return $(this.note.bodyHtml).unwrap().html(); }, - hasMoreCommits() { - return $(this.note.bodyHtml).filter('ul').children().length > MAX_VISIBLE_COMMIT_LIST_COUNT; - }, - descriptionVersion() { - return this.descriptionVersions[this.note.description_version_id]; + descriptionVersionId() { + return getIdFromGraphQLId(this.systemNoteDescriptionVersion?.id); }, noteId() { return getIdFromGraphQLId(this.note.id); }, + descriptionVersion() { + return this.descriptionVersions[this.descriptionVersionId]; + }, }, mounted() { renderGFM(this.$refs['gfm-content']); }, - methods: { - fetchDescriptionVersion() {}, - softDeleteDescriptionVersion() {}, - - async toggleDiff() { - this.showLines = !this.showLines; - - if (!this.lines.length) { - this.loadingDiff = true; - const { data } = await axios.get(this.note.outdated_line_change_path); - - this.lines = data.map((l) => ({ - ...l, - rich_text: l.rich_text.replace(/^[+ -]/, ''), - })); - this.loadingDiff = false; - } - }, - }, safeHtmlConfig: { ADD_TAGS: ['use'], // to support icon SVGs }, @@ -141,10 +116,7 @@ export default { :is-system-note="true" > <span ref="gfm-content" v-safe-html="actionTextHtml"></span> - <template - v-if="canSeeDescriptionVersion || note.outdated_line_change_path" - #extra-controls - > + <template v-if="canSeeDescriptionVersion" #extra-controls> · <gl-button v-if="canSeeDescriptionVersion" @@ -155,36 +127,20 @@ export default { @click="toggleDescriptionVersion" >{{ __('Compare with previous version') }}</gl-button > - <gl-button - v-if="note.outdated_line_change_path" - :icon="showLines ? 'chevron-up' : 'chevron-down'" - variant="link" - data-testid="outdated-lines-change-btn" - class="gl-vertical-align-text-bottom gl-font-sm!" - @click="toggleDiff" - > - {{ __('Compare changes') }} - </gl-button> </template> </note-header> </div> <div class="note-body"> - <div - v-safe-html="note.bodyHtml" - :class="{ 'system-note-commit-list': hasMoreCommits, 'hide-shade': expanded }" - class="note-text md" - ></div> - <div v-if="hasMoreCommits" class="flex-list"> - <div class="system-note-commit-list-toggler flex-row" @click="expanded = !expanded"> - <gl-icon :name="toggleIcon" :size="8" class="gl-mr-2" /> - <span>{{ __('Toggle commit list') }}</span> - </div> - </div> - <div v-if="shouldShowDescriptionVersion" class="description-version pt-2"> + <div v-if="shouldShowDescriptionVersion" class="description-version gl-pt-3! gl-pl-4"> <pre v-if="isLoadingDescriptionVersion" class="loading-state"> <gl-skeleton-loader /> </pre> - <pre v-else v-safe-html="descriptionVersion" class="wrapper mt-2"></pre> + <pre + v-else + v-safe-html="descriptionVersion" + data-testid="description-version-diff" + class="wrapper gl-mt-3" + ></pre> <gl-button v-if="displayDeleteButton" v-gl-tooltip @@ -198,39 +154,6 @@ export default { @click="deleteDescriptionVersion" /> </div> - <div - v-if="lines.length && showLines" - class="diff-content outdated-lines-wrapper gl-border-solid gl-border-1 gl-border-gray-200 gl-mt-4 gl-rounded-small gl-overflow-hidden" - > - <table - :class="$options.userColorSchemeClass" - class="code js-syntax-highlight" - data-testid="outdated-lines" - > - <tr v-for="line in lines" v-once :key="line.line_code" class="line_holder"> - <td - :class="line.type" - class="diff-line-num old_line gl-border-bottom-0! gl-border-top-0! gl-border-0! gl-rounded-0!" - > - {{ line.old_line }} - </td> - <td - :class="line.type" - class="diff-line-num new_line gl-border-bottom-0! gl-border-top-0!" - > - {{ line.new_line }} - </td> - <td - :class="line.type" - class="line_content gl-display-table-cell! gl-border-0! gl-rounded-0!" - v-html="line.rich_text /* eslint-disable-line vue/no-v-html */" - ></td> - </tr> - </table> - </div> - <div v-else-if="showLines" class="mt-4"> - <gl-skeleton-loader /> - </div> </div> </div> </timeline-entry-item> diff --git a/app/assets/javascripts/work_items/components/work_item_description.vue b/app/assets/javascripts/work_items/components/work_item_description.vue index a4cbc430b84..279acc98cd4 100644 --- a/app/assets/javascripts/work_items/components/work_item_description.vue +++ b/app/assets/javascripts/work_items/components/work_item_description.vue @@ -229,13 +229,13 @@ export default { <div> <gl-form-group v-if="isEditing" - class="gl-mb-5 gl-border-t gl-pt-6" + class="gl-mb-5 gl-border-t gl-pt-6 common-note-form" :label="__('Description')" label-for="work-item-description" > <markdown-editor v-if="glFeatures.workItemsMvc" - class="gl-my-3 common-note-form" + class="gl-my-5" :value="descriptionText" :render-markdown-path="markdownPreviewPath" :markdown-docs-path="$options.markdownDocsPath" diff --git a/app/assets/javascripts/work_items/components/work_item_notes.vue b/app/assets/javascripts/work_items/components/work_item_notes.vue index 092b90a5731..8fc460294e6 100644 --- a/app/assets/javascripts/work_items/components/work_item_notes.vue +++ b/app/assets/javascripts/work_items/components/work_item_notes.vue @@ -21,6 +21,7 @@ import { updateCacheAfterDeletingNote, } from '~/work_items/graphql/cache_utils'; import { getLocationHash } from '~/lib/utils/url_utility'; +import { collapseSystemNotes } from '~/work_items/notes/collapse_utils'; import WorkItemDiscussion from '~/work_items/components/notes/work_item_discussion.vue'; import WorkItemHistoryOnlyFilterNote from '~/work_items/components/notes/work_item_history_only_filter_note.vue'; import workItemNoteCreatedSubscription from '~/work_items/graphql/notes/work_item_note_created.subscription.graphql'; @@ -128,7 +129,9 @@ export default { notesArray() { const notes = this.workItemNotes?.nodes || []; - const visibleNotes = notes.filter((note) => { + let visibleNotes = collapseSystemNotes(notes); + + visibleNotes = visibleNotes.filter((note) => { const isSystemNote = this.isSystemNote(note); if (this.discussionFilter === WORK_ITEM_NOTES_FILTER_ONLY_COMMENTS && isSystemNote) { @@ -145,6 +148,7 @@ export default { if (this.sortOrder === DESC) { return [...visibleNotes].reverse(); } + return visibleNotes; }, commentsDisabled() { diff --git a/app/assets/javascripts/work_items/graphql/notes/create_work_item_note.mutation.graphql b/app/assets/javascripts/work_items/graphql/notes/create_work_item_note.mutation.graphql index 5050aa7cbda..3286895215f 100644 --- a/app/assets/javascripts/work_items/graphql/notes/create_work_item_note.mutation.graphql +++ b/app/assets/javascripts/work_items/graphql/notes/create_work_item_note.mutation.graphql @@ -1,4 +1,4 @@ -#import "./work_item_note.fragment.graphql" +#import "ee_else_ce/work_items/graphql/notes/work_item_note.fragment.graphql" mutation createWorkItemNote($input: CreateNoteInput!) { createNote(input: $input) { diff --git a/app/assets/javascripts/work_items/graphql/notes/update_work_item_note.mutation.graphql b/app/assets/javascripts/work_items/graphql/notes/update_work_item_note.mutation.graphql index 3da8e7677e4..eb52eb912e7 100644 --- a/app/assets/javascripts/work_items/graphql/notes/update_work_item_note.mutation.graphql +++ b/app/assets/javascripts/work_items/graphql/notes/update_work_item_note.mutation.graphql @@ -1,4 +1,4 @@ -#import "./work_item_note.fragment.graphql" +#import "ee_else_ce/work_items/graphql/notes/work_item_note.fragment.graphql" mutation updateWorkItemNote($input: UpdateNoteInput!) { updateNote(input: $input) { diff --git a/app/assets/javascripts/work_items/graphql/notes/work_item_discussion_note.fragment.graphql b/app/assets/javascripts/work_items/graphql/notes/work_item_discussion_note.fragment.graphql index 58561e33e53..635faf27892 100644 --- a/app/assets/javascripts/work_items/graphql/notes/work_item_discussion_note.fragment.graphql +++ b/app/assets/javascripts/work_items/graphql/notes/work_item_discussion_note.fragment.graphql @@ -1,5 +1,5 @@ #import "~/graphql_shared/fragments/user.fragment.graphql" -#import "./work_item_note.fragment.graphql" +#import "ee_else_ce/work_items/graphql/notes/work_item_note.fragment.graphql" fragment WorkItemDiscussionNote on Note { id diff --git a/app/assets/javascripts/work_items/graphql/notes/work_item_note.fragment.graphql b/app/assets/javascripts/work_items/graphql/notes/work_item_note.fragment.graphql index 93616c39e55..973c6fde474 100644 --- a/app/assets/javascripts/work_items/graphql/notes/work_item_note.fragment.graphql +++ b/app/assets/javascripts/work_items/graphql/notes/work_item_note.fragment.graphql @@ -28,4 +28,11 @@ fragment WorkItemNote on Note { resolveNote repositionNote } + systemNoteMetadata { + id + descriptionVersion { + id + description + } + } } diff --git a/app/assets/javascripts/work_items/graphql/notes/work_item_note_updated.subscription.graphql b/app/assets/javascripts/work_items/graphql/notes/work_item_note_updated.subscription.graphql index c68d5f491cf..1a6f4e44ee0 100644 --- a/app/assets/javascripts/work_items/graphql/notes/work_item_note_updated.subscription.graphql +++ b/app/assets/javascripts/work_items/graphql/notes/work_item_note_updated.subscription.graphql @@ -1,4 +1,4 @@ -#import "./work_item_note.fragment.graphql" +#import "ee_else_ce/work_items/graphql/notes/work_item_note.fragment.graphql" subscription workItemNoteUpdated($noteableId: NoteableID) { workItemNoteUpdated(noteableId: $noteableId) { diff --git a/app/assets/javascripts/work_items/graphql/notes/work_item_notes_by_iid.query.graphql b/app/assets/javascripts/work_items/graphql/notes/work_item_notes_by_iid.query.graphql index 6b37c68cb43..6022b280d72 100644 --- a/app/assets/javascripts/work_items/graphql/notes/work_item_notes_by_iid.query.graphql +++ b/app/assets/javascripts/work_items/graphql/notes/work_item_notes_by_iid.query.graphql @@ -1,5 +1,5 @@ #import "~/graphql_shared/fragments/page_info.fragment.graphql" -#import "./work_item_note.fragment.graphql" +#import "ee_else_ce/work_items/graphql/notes/work_item_note.fragment.graphql" query workItemNotesByIid($fullPath: ID!, $iid: String, $after: String, $pageSize: Int) { workspace: project(fullPath: $fullPath) { diff --git a/app/assets/javascripts/work_items/mixins/description_version_history.js b/app/assets/javascripts/work_items/mixins/description_version_history.js new file mode 100644 index 00000000000..d1006e37a70 --- /dev/null +++ b/app/assets/javascripts/work_items/mixins/description_version_history.js @@ -0,0 +1,14 @@ +// Placeholder for GitLab FOSS +// Actual implementation: ee/app/assets/javascripts/notes/mixins/description_version_history.js +export default { + computed: { + canSeeDescriptionVersion() {}, + displayDeleteButton() {}, + shouldShowDescriptionVersion() {}, + descriptionVersionToggleIcon() {}, + }, + methods: { + toggleDescriptionVersion() {}, + deleteDescriptionVersion() {}, + }, +}; diff --git a/app/assets/javascripts/work_items/notes/collapse_utils.js b/app/assets/javascripts/work_items/notes/collapse_utils.js new file mode 100644 index 00000000000..db7b4530e2a --- /dev/null +++ b/app/assets/javascripts/work_items/notes/collapse_utils.js @@ -0,0 +1,92 @@ +import { DESCRIPTION_TYPE, TIME_DIFFERENCE_VALUE } from '~/notes/constants'; + +/** + * Checks the time difference between two notes from their 'created_at' dates + * returns an integer + */ +export const getTimeDifferenceInMinutes = (noteBeginning, noteEnd) => { + const descriptionNoteBegin = new Date(noteBeginning.createdAt); + const descriptionNoteEnd = new Date(noteEnd.createdAt); + const timeDifferenceMinutes = (descriptionNoteEnd - descriptionNoteBegin) / 1000 / 60; + + return Math.ceil(timeDifferenceMinutes); +}; + +/** + * Checks if a note is a system note and if the content is description + * + * @param {Object} note + * @returns {Boolean} + */ +export const isDescriptionSystemNote = (note) => { + return note.system && note.body === DESCRIPTION_TYPE; +}; + +/** + * Collapses the system notes of a description type, e.g. Changed the description, n minutes ago + * the notes will collapse as long as they happen no more than 10 minutes away from each away + * in between the notes can be anything, another type of system note + * (such as 'changed the weight') or a comment. + * + * @param {Array} notes + * @returns {Array} + */ +export const collapseSystemNotes = (notes) => { + let lastDescriptionSystemNote = null; + let lastDescriptionSystemNoteIndex = -1; + + return notes.reduce((acc, currentNote) => { + const note = currentNote.notes.nodes[0]; + let lastStartVersionId = ''; + + if (isDescriptionSystemNote(note)) { + // is it the first one? + if (!lastDescriptionSystemNote) { + lastDescriptionSystemNote = note; + } else { + const timeDifferenceMinutes = getTimeDifferenceInMinutes(lastDescriptionSystemNote, note); + + // are they less than 10 minutes apart from the same user? + if ( + timeDifferenceMinutes > TIME_DIFFERENCE_VALUE || + note.author.id !== lastDescriptionSystemNote.author.id || + lastDescriptionSystemNote.systemNoteMetadata.descriptionVersion?.deleted + ) { + // update the previous system note + lastDescriptionSystemNote = note; + } else { + // set the first version to fetch grouped system note versions + + lastStartVersionId = lastDescriptionSystemNote.systemNoteMetadata.descriptionVersion.id; + + // delete the previous one + acc.splice(lastDescriptionSystemNoteIndex, 1); + } + } + + // update the previous system note index + lastDescriptionSystemNoteIndex = acc.length; + + acc.push({ + notes: { + nodes: [ + { + ...note, + systemNoteMetadata: { + ...note.systemNoteMetadata, + descriptionVersion: { + ...note.systemNoteMetadata.descriptionVersion, + startVersionId: lastStartVersionId, + }, + }, + }, + ], + }, + }); + } else { + acc.push(currentNote); + } + + return acc; + }, []); +}; |