diff options
Diffstat (limited to 'app/assets/javascripts/vue_shared/components')
90 files changed, 750 insertions, 337 deletions
diff --git a/app/assets/javascripts/vue_shared/components/actions_button.vue b/app/assets/javascripts/vue_shared/components/actions_button.vue index 2dc2c27f7ea..13472b48e84 100644 --- a/app/assets/javascripts/vue_shared/components/actions_button.vue +++ b/app/assets/javascripts/vue_shared/components/actions_button.vue @@ -76,14 +76,13 @@ export default { <template v-for="(action, index) in actions"> <gl-dropdown-item :key="action.key" - class="gl-dropdown-item-deprecated-adapter" :is-check-item="true" :is-checked="action.key === selectedAction.key" :secondary-text="action.secondaryText" :data-testid="`action_${action.key}`" @click="handleItemClick(action)" > - {{ action.text }} + <span class="gl-font-weight-bold">{{ action.text }}</span> </gl-dropdown-item> <gl-dropdown-divider v-if="index != actions.length - 1" :key="action.key + '_divider'" /> </template> diff --git a/app/assets/javascripts/vue_shared/components/alert_details_table.vue b/app/assets/javascripts/vue_shared/components/alert_details_table.vue index 655b867574d..3d49a1cb1c5 100644 --- a/app/assets/javascripts/vue_shared/components/alert_details_table.vue +++ b/app/assets/javascripts/vue_shared/components/alert_details_table.vue @@ -1,12 +1,12 @@ <script> import { GlLoadingIcon, GlTable } from '@gitlab/ui'; import { reduce } from 'lodash'; -import { s__ } from '~/locale'; import { capitalizeFirstCharacter, convertToSentenceCase, splitCamelCase, } from '~/lib/utils/text_utility'; +import { s__ } from '~/locale'; const thClass = 'gl-bg-transparent! gl-border-1! gl-border-b-solid! gl-border-gray-200!'; const tdClass = 'gl-border-gray-100! gl-p-5!'; diff --git a/app/assets/javascripts/vue_shared/components/awards_list.vue b/app/assets/javascripts/vue_shared/components/awards_list.vue index c1da2b8c305..ce67d33d4a1 100644 --- a/app/assets/javascripts/vue_shared/components/awards_list.vue +++ b/app/assets/javascripts/vue_shared/components/awards_list.vue @@ -1,9 +1,9 @@ <script> /* eslint-disable vue/no-v-html */ -import { groupBy } from 'lodash'; import { GlIcon, GlButton, GlTooltipDirective } from '@gitlab/ui'; -import { glEmojiTag } from '../../emoji'; +import { groupBy } from 'lodash'; import { __, sprintf } from '~/locale'; +import { glEmojiTag } from '../../emoji'; // Internal constant, specific to this component, used when no `currentUserId` is given const NO_USER_ID = -1; diff --git a/app/assets/javascripts/vue_shared/components/blob_viewers/mixins.js b/app/assets/javascripts/vue_shared/components/blob_viewers/mixins.js index 6f7723955bf..db61d0f6b05 100644 --- a/app/assets/javascripts/vue_shared/components/blob_viewers/mixins.js +++ b/app/assets/javascripts/vue_shared/components/blob_viewers/mixins.js @@ -1,5 +1,5 @@ -import { SNIPPET_MEASURE_BLOBS_CONTENT } from '~/performance/constants'; import eventHub from '~/blob/components/eventhub'; +import { SNIPPET_MEASURE_BLOBS_CONTENT } from '~/performance/constants'; export default { props: { diff --git a/app/assets/javascripts/vue_shared/components/blob_viewers/rich_viewer.vue b/app/assets/javascripts/vue_shared/components/blob_viewers/rich_viewer.vue index d0f5570db6b..a8a053c0d9e 100644 --- a/app/assets/javascripts/vue_shared/components/blob_viewers/rich_viewer.vue +++ b/app/assets/javascripts/vue_shared/components/blob_viewers/rich_viewer.vue @@ -1,8 +1,8 @@ <script> import { GlSafeHtmlDirective as SafeHtml } from '@gitlab/ui'; +import { handleBlobRichViewer } from '~/blob/viewer'; import MarkdownFieldView from '~/vue_shared/components/markdown/field_view.vue'; import ViewerMixin from './mixins'; -import { handleBlobRichViewer } from '~/blob/viewer'; export default { components: { diff --git a/app/assets/javascripts/vue_shared/components/blob_viewers/simple_viewer.vue b/app/assets/javascripts/vue_shared/components/blob_viewers/simple_viewer.vue index 646e1703f1e..5bb31f55e6c 100644 --- a/app/assets/javascripts/vue_shared/components/blob_viewers/simple_viewer.vue +++ b/app/assets/javascripts/vue_shared/components/blob_viewers/simple_viewer.vue @@ -1,8 +1,8 @@ <script> /* eslint-disable vue/no-v-html */ import { GlIcon } from '@gitlab/ui'; -import ViewerMixin from './mixins'; import { HIGHLIGHT_CLASS_NAME } from './constants'; +import ViewerMixin from './mixins'; export default { components: { diff --git a/app/assets/javascripts/vue_shared/components/clone_dropdown.vue b/app/assets/javascripts/vue_shared/components/clone_dropdown.vue index 5c6bd5892ae..cd5f63afc79 100644 --- a/app/assets/javascripts/vue_shared/components/clone_dropdown.vue +++ b/app/assets/javascripts/vue_shared/components/clone_dropdown.vue @@ -6,8 +6,8 @@ import { GlButton, GlTooltipDirective, } from '@gitlab/ui'; -import { __, sprintf } from '~/locale'; import { getHTTPProtocol } from '~/lib/utils/url_utility'; +import { __, sprintf } from '~/locale'; export default { components: { diff --git a/app/assets/javascripts/vue_shared/components/color_picker/color_picker.vue b/app/assets/javascripts/vue_shared/components/color_picker/color_picker.vue index 6977692e30c..0ff33e462b4 100644 --- a/app/assets/javascripts/vue_shared/components/color_picker/color_picker.vue +++ b/app/assets/javascripts/vue_shared/components/color_picker/color_picker.vue @@ -3,12 +3,16 @@ * Renders a color picker input with preset colors to choose from * * @example - * <color-picker :label="__('Background color')" set-color="#FF0000" /> + * <color-picker + :invalid-feedback="__('Please enter a valid hex (#RRGGBB or #RGB) color value')" + :label="__('Background color')" + :value="#FF0000" + state="isValidColor" + /> */ import { GlFormGroup, GlFormInput, GlFormInputGroup, GlLink, GlTooltipDirective } from '@gitlab/ui'; import { __ } from '~/locale'; -const VALID_RGB_HEX_COLOR = /^#([0-9A-F]{3}){1,2}$/i; const PREVIEW_COLOR_DEFAULT_CLASSES = 'gl-relative gl-w-7 gl-bg-gray-10 gl-rounded-top-left-base gl-rounded-bottom-left-base'; @@ -24,21 +28,26 @@ export default { GlTooltip: GlTooltipDirective, }, props: { + invalidFeedback: { + type: String, + required: false, + default: __('Please enter a valid hex (#RRGGBB or #RGB) color value'), + }, label: { type: String, required: false, default: '', }, - setColor: { + value: { type: String, required: false, default: '', }, - }, - data() { - return { - selectedColor: this.setColor.trim() || '', - }; + state: { + type: Boolean, + required: false, + default: null, + }, }, computed: { description() { @@ -50,46 +59,30 @@ export default { return gon.suggested_label_colors; }, previewColor() { - if (this.isValidColor) { - return { backgroundColor: this.selectedColor }; + if (this.state) { + return { backgroundColor: this.value }; } return {}; }, previewColorClasses() { - const borderStyle = this.isInvalidColor - ? 'gl-inset-border-1-red-500' - : 'gl-inset-border-1-gray-400'; + const borderStyle = + this.state === false ? 'gl-inset-border-1-red-500' : 'gl-inset-border-1-gray-400'; return `${PREVIEW_COLOR_DEFAULT_CLASSES} ${borderStyle}`; }, hasSuggestedColors() { return Object.keys(this.suggestedColors).length; }, - isInvalidColor() { - return this.isValidColor === false; - }, - isValidColor() { - if (this.selectedColor === '') { - return null; - } - - return VALID_RGB_HEX_COLOR.test(this.selectedColor); - }, }, methods: { handleColorChange(color) { - this.selectedColor = color.trim(); - - if (this.isValidColor) { - this.$emit('input', this.selectedColor); - } + this.$emit('input', color.trim()); }, }, i18n: { fullDescription: __('Choose any color. Or you can choose one of the suggested colors below'), shortDescription: __('Choose any color'), - invalid: __('Please enter a valid hex (#RRGGBB or #RGB) color value'), }, }; </script> @@ -100,17 +93,17 @@ export default { :label="label" label-for="color-picker" :description="description" - :invalid-feedback="this.$options.i18n.invalid" - :state="isValidColor" + :invalid-feedback="invalidFeedback" + :state="state" :class="{ 'gl-mb-3!': hasSuggestedColors }" > <gl-form-input-group id="color-picker" - :state="isValidColor" max-length="7" type="text" class="gl-align-center gl-rounded-0 gl-rounded-top-right-base gl-rounded-bottom-right-base" - :value="selectedColor" + :value="value" + :state="state" @input="handleColorChange" > <template #prepend> @@ -119,7 +112,7 @@ export default { type="color" class="gl-absolute gl-top-0 gl-left-0 gl-h-full! gl-p-0! gl-m-0! gl-cursor-pointer gl-opacity-0" tabindex="-1" - :value="selectedColor" + :value="value" @input="handleColorChange" /> </div> diff --git a/app/assets/javascripts/vue_shared/components/commit.vue b/app/assets/javascripts/vue_shared/components/commit.vue index deca934e283..d1eee62683b 100644 --- a/app/assets/javascripts/vue_shared/components/commit.vue +++ b/app/assets/javascripts/vue_shared/components/commit.vue @@ -1,6 +1,6 @@ <script> -import { isString, isEmpty } from 'lodash'; import { GlTooltipDirective, GlLink, GlIcon } from '@gitlab/ui'; +import { isString, isEmpty } from 'lodash'; import { __, sprintf } from '~/locale'; import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate.vue'; import UserAvatarLink from './user_avatar/user_avatar_link.vue'; @@ -133,6 +133,9 @@ export default { ? sprintf(__("%{username}'s avatar"), { username: this.author.username }) : null; }, + refUrl() { + return this.commitRef.ref_url || this.commitRef.path; + }, }, }; </script> @@ -156,9 +159,10 @@ export default { <gl-link v-else v-gl-tooltip - :href="commitRef.ref_url" + :href="refUrl" :title="commitRef.name" class="ref-name" + data-testid="ref-name" >{{ commitRef.name }}</gl-link > </template> diff --git a/app/assets/javascripts/vue_shared/components/content_viewer/content_viewer.vue b/app/assets/javascripts/vue_shared/components/content_viewer/content_viewer.vue index 9ff35132ac9..1370f7b2a8c 100644 --- a/app/assets/javascripts/vue_shared/components/content_viewer/content_viewer.vue +++ b/app/assets/javascripts/vue_shared/components/content_viewer/content_viewer.vue @@ -1,7 +1,7 @@ <script> -import MarkdownViewer from './viewers/markdown_viewer.vue'; -import ImageViewer from './viewers/image_viewer.vue'; import DownloadViewer from './viewers/download_viewer.vue'; +import ImageViewer from './viewers/image_viewer.vue'; +import MarkdownViewer from './viewers/markdown_viewer.vue'; export default { components: { diff --git a/app/assets/javascripts/vue_shared/components/content_viewer/viewers/image_viewer.vue b/app/assets/javascripts/vue_shared/components/content_viewer/viewers/image_viewer.vue index 9ece6a52805..a49eb7fd611 100644 --- a/app/assets/javascripts/vue_shared/components/content_viewer/viewers/image_viewer.vue +++ b/app/assets/javascripts/vue_shared/components/content_viewer/viewers/image_viewer.vue @@ -1,6 +1,7 @@ <script> import { throttle } from 'lodash'; -import { numberToHumanSize } from '../../../../lib/utils/number_utils'; +import { numberToHumanSize } from '~/lib/utils/number_utils'; +import { encodeSaferUrl } from '~/lib/utils/url_utility'; export default { props: { @@ -43,6 +44,9 @@ export default { hasDimensions() { return this.width && this.height; }, + safePath() { + return encodeSaferUrl(this.path); + }, }, beforeDestroy() { window.removeEventListener('resize', this.resizeThrottled, false); @@ -84,7 +88,7 @@ export default { <template> <div data-testid="image-viewer" data-qa-selector="image_viewer_container"> <div :class="innerCssClasses" class="position-relative"> - <img ref="contentImg" :src="path" @load="onImgLoad" /> + <img ref="contentImg" :src="safePath" @load="onImgLoad" /> <slot name="image-overlay" :rendered-width="renderedWidth" diff --git a/app/assets/javascripts/vue_shared/components/content_viewer/viewers/markdown_viewer.vue b/app/assets/javascripts/vue_shared/components/content_viewer/viewers/markdown_viewer.vue index 24386c90954..3790a509f26 100644 --- a/app/assets/javascripts/vue_shared/components/content_viewer/viewers/markdown_viewer.vue +++ b/app/assets/javascripts/vue_shared/components/content_viewer/viewers/markdown_viewer.vue @@ -1,9 +1,8 @@ <script> /* eslint-disable vue/no-v-html */ +import { GlDeprecatedSkeletonLoading as GlSkeletonLoading } from '@gitlab/ui'; import $ from 'jquery'; import '~/behaviors/markdown/render_gfm'; - -import { GlDeprecatedSkeletonLoading as GlSkeletonLoading } from '@gitlab/ui'; import { forEach, escape } from 'lodash'; import axios from '~/lib/utils/axios_utils'; import { __ } from '~/locale'; diff --git a/app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker.vue b/app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker.vue index d0c2672b162..1a96cabf755 100644 --- a/app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker.vue +++ b/app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker.vue @@ -1,8 +1,7 @@ <script> import { GlIcon, GlButton, GlDropdown, GlDropdownItem, GlFormGroup } from '@gitlab/ui'; -import { __, sprintf } from '~/locale'; - import { convertToFixedRange, isEqualTimeRanges, findTimeRange } from '~/lib/utils/datetime_range'; +import { __, sprintf } from '~/locale'; import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate.vue'; import DateTimePickerInput from './date_time_picker_input.vue'; diff --git a/app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker_input.vue b/app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker_input.vue index 39c1caf928e..190d4e1f104 100644 --- a/app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker_input.vue +++ b/app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker_input.vue @@ -1,6 +1,6 @@ <script> -import { uniqueId } from 'lodash'; import { GlFormGroup, GlFormInput } from '@gitlab/ui'; +import { uniqueId } from 'lodash'; import { __, sprintf } from '~/locale'; import { dateFormats } from './date_time_picker_lib'; diff --git a/app/assets/javascripts/vue_shared/components/diff_viewer/diff_viewer.vue b/app/assets/javascripts/vue_shared/components/diff_viewer/diff_viewer.vue index e755494a668..7080e046b30 100644 --- a/app/assets/javascripts/vue_shared/components/diff_viewer/diff_viewer.vue +++ b/app/assets/javascripts/vue_shared/components/diff_viewer/diff_viewer.vue @@ -1,9 +1,9 @@ <script> import { diffViewerModes, diffModes } from '~/ide/constants'; -import ImageDiffViewer from './viewers/image_diff_viewer.vue'; import DownloadDiffViewer from './viewers/download_diff_viewer.vue'; -import RenamedFile from './viewers/renamed.vue'; +import ImageDiffViewer from './viewers/image_diff_viewer.vue'; import ModeChanged from './viewers/mode_changed.vue'; +import RenamedFile from './viewers/renamed.vue'; export default { props: { diff --git a/app/assets/javascripts/vue_shared/components/diff_viewer/viewers/image_diff/onion_skin_viewer.vue b/app/assets/javascripts/vue_shared/components/diff_viewer/viewers/image_diff/onion_skin_viewer.vue index 433aafdeb9e..a3d9b0ace34 100644 --- a/app/assets/javascripts/vue_shared/components/diff_viewer/viewers/image_diff/onion_skin_viewer.vue +++ b/app/assets/javascripts/vue_shared/components/diff_viewer/viewers/image_diff/onion_skin_viewer.vue @@ -1,6 +1,6 @@ <script> -import { pixeliseValue } from '../../../lib/utils/dom_utils'; import ImageViewer from '../../../content_viewer/viewers/image_viewer.vue'; +import { pixeliseValue } from '../../../lib/utils/dom_utils'; export default { components: { diff --git a/app/assets/javascripts/vue_shared/components/diff_viewer/viewers/image_diff/swipe_viewer.vue b/app/assets/javascripts/vue_shared/components/diff_viewer/viewers/image_diff/swipe_viewer.vue index acca6ba117f..41acc63cea9 100644 --- a/app/assets/javascripts/vue_shared/components/diff_viewer/viewers/image_diff/swipe_viewer.vue +++ b/app/assets/javascripts/vue_shared/components/diff_viewer/viewers/image_diff/swipe_viewer.vue @@ -1,7 +1,7 @@ <script> import { throttle } from 'lodash'; -import { pixeliseValue } from '../../../lib/utils/dom_utils'; import ImageViewer from '../../../content_viewer/viewers/image_viewer.vue'; +import { pixeliseValue } from '../../../lib/utils/dom_utils'; export default { components: { diff --git a/app/assets/javascripts/vue_shared/components/diff_viewer/viewers/image_diff_viewer.vue b/app/assets/javascripts/vue_shared/components/diff_viewer/viewers/image_diff_viewer.vue index 00033145603..f5ac65bcd1f 100644 --- a/app/assets/javascripts/vue_shared/components/diff_viewer/viewers/image_diff_viewer.vue +++ b/app/assets/javascripts/vue_shared/components/diff_viewer/viewers/image_diff_viewer.vue @@ -1,9 +1,9 @@ <script> import ImageViewer from '../../content_viewer/viewers/image_viewer.vue'; -import TwoUpViewer from './image_diff/two_up_viewer.vue'; -import SwipeViewer from './image_diff/swipe_viewer.vue'; -import OnionSkinViewer from './image_diff/onion_skin_viewer.vue'; import { diffModes, imageViewMode } from '../constants'; +import OnionSkinViewer from './image_diff/onion_skin_viewer.vue'; +import SwipeViewer from './image_diff/swipe_viewer.vue'; +import TwoUpViewer from './image_diff/two_up_viewer.vue'; export default { components: { diff --git a/app/assets/javascripts/vue_shared/components/diff_viewer/viewers/renamed.vue b/app/assets/javascripts/vue_shared/components/diff_viewer/viewers/renamed.vue index eba6dd4d14c..d6f99e9a049 100644 --- a/app/assets/javascripts/vue_shared/components/diff_viewer/viewers/renamed.vue +++ b/app/assets/javascripts/vue_shared/components/diff_viewer/viewers/renamed.vue @@ -1,8 +1,7 @@ <script> -import { mapActions } from 'vuex'; import { GlAlert, GlLink, GlLoadingIcon, GlSprintf } from '@gitlab/ui'; +import { mapActions } from 'vuex'; -import { __ } from '~/locale'; import { TRANSITION_LOAD_START, TRANSITION_LOAD_ERROR, @@ -14,6 +13,7 @@ import { RENAMED_DIFF_TRANSITIONS, } from '~/diffs/constants'; import { truncateSha } from '~/lib/utils/text_utility'; +import { __ } from '~/locale'; export default { STATE_LOADING, diff --git a/app/assets/javascripts/vue_shared/components/dismissible_feedback_alert.vue b/app/assets/javascripts/vue_shared/components/dismissible_feedback_alert.vue index 2a28b13e7bf..c4dfcf93a18 100644 --- a/app/assets/javascripts/vue_shared/components/dismissible_feedback_alert.vue +++ b/app/assets/javascripts/vue_shared/components/dismissible_feedback_alert.vue @@ -1,7 +1,7 @@ <script> import { GlAlert, GlSprintf, GlLink } from '@gitlab/ui'; -import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue'; import { slugifyWithUnderscore } from '~/lib/utils/text_utility'; +import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue'; export default { components: { diff --git a/app/assets/javascripts/vue_shared/components/dropdown/dropdown_button.vue b/app/assets/javascripts/vue_shared/components/dropdown/dropdown_button.vue index 7e82d8f3f9c..eb8400e81c7 100644 --- a/app/assets/javascripts/vue_shared/components/dropdown/dropdown_button.vue +++ b/app/assets/javascripts/vue_shared/components/dropdown/dropdown_button.vue @@ -36,10 +36,8 @@ export default { aria-expanded="false" > <gl-loading-icon v-show="isLoading" :inline="true" /> - <template> - <slot v-if="$slots.default"></slot> - <span v-else class="dropdown-toggle-text"> {{ toggleText }} </span> - </template> + <slot v-if="$slots.default"></slot> + <span v-else class="dropdown-toggle-text"> {{ toggleText }} </span> <gl-icon v-show="!isLoading" class="gl-absolute gl-top-3 gl-right-3 gl-text-gray-500" diff --git a/app/assets/javascripts/vue_shared/components/editor_lite.vue b/app/assets/javascripts/vue_shared/components/editor_lite.vue index 7218b84cf8a..c3bddabea21 100644 --- a/app/assets/javascripts/vue_shared/components/editor_lite.vue +++ b/app/assets/javascripts/vue_shared/components/editor_lite.vue @@ -1,7 +1,7 @@ <script> import { debounce } from 'lodash'; +import { CONTENT_UPDATE_DEBOUNCE, EDITOR_READY_EVENT } from '~/editor/constants'; import Editor from '~/editor/editor_lite'; -import { CONTENT_UPDATE_DEBOUNCE } from '~/editor/constants'; function initEditorLite({ el, ...args }) { const editor = new Editor({ @@ -88,6 +88,7 @@ export default { return this.editor; }, }, + readyEvent: EDITOR_READY_EVENT, }; </script> <template> @@ -95,7 +96,7 @@ export default { :id="`editor-lite-${fileGlobalId}`" ref="editor" data-editor-loading - @editor-ready="$emit('editor-ready')" + @[$options.readyEvent]="$emit($options.readyEvent)" > <pre class="editor-loading-content">{{ value }}</pre> </div> diff --git a/app/assets/javascripts/vue_shared/components/file_finder/index.vue b/app/assets/javascripts/vue_shared/components/file_finder/index.vue index 27933f87929..4ec54b33bce 100644 --- a/app/assets/javascripts/vue_shared/components/file_finder/index.vue +++ b/app/assets/javascripts/vue_shared/components/file_finder/index.vue @@ -1,10 +1,10 @@ <script> +import { GlIcon } from '@gitlab/ui'; import fuzzaldrinPlus from 'fuzzaldrin-plus'; import Mousetrap from 'mousetrap'; import VirtualList from 'vue-virtual-scroll-list'; -import { GlIcon } from '@gitlab/ui'; -import Item from './item.vue'; import { UP_KEY_CODE, DOWN_KEY_CODE, ENTER_KEY_CODE, ESC_KEY_CODE } from '~/lib/utils/keycodes'; +import Item from './item.vue'; export const MAX_FILE_FINDER_RESULTS = 40; export const FILE_FINDER_ROW_HEIGHT = 55; diff --git a/app/assets/javascripts/vue_shared/components/file_finder/item.vue b/app/assets/javascripts/vue_shared/components/file_finder/item.vue index 4c496ba3f9b..7816c1d74ec 100644 --- a/app/assets/javascripts/vue_shared/components/file_finder/item.vue +++ b/app/assets/javascripts/vue_shared/components/file_finder/item.vue @@ -1,8 +1,8 @@ <script> -import fuzzaldrinPlus from 'fuzzaldrin-plus'; import { GlIcon } from '@gitlab/ui'; -import FileIcon from '../file_icon.vue'; +import fuzzaldrinPlus from 'fuzzaldrin-plus'; import ChangedFileIcon from '../changed_file_icon.vue'; +import FileIcon from '../file_icon.vue'; const MAX_PATH_LENGTH = 60; diff --git a/app/assets/javascripts/vue_shared/components/file_icon.vue b/app/assets/javascripts/vue_shared/components/file_icon.vue index 6190b07962d..8ac8a3beb7d 100644 --- a/app/assets/javascripts/vue_shared/components/file_icon.vue +++ b/app/assets/javascripts/vue_shared/components/file_icon.vue @@ -1,7 +1,7 @@ <script> import { GlLoadingIcon, GlIcon } from '@gitlab/ui'; -import getIconForFile from './file_icon/file_icon_map'; import { FILE_SYMLINK_MODE } from '../constants'; +import getIconForFile from './file_icon/file_icon_map'; /* This is a re-usable vue component for rendering a svg sprite icon @@ -90,6 +90,12 @@ export default { <svg v-else-if="!folder" :key="spriteHref" :class="[iconSizeClass, cssClasses]"> <use v-bind="{ 'xlink:href': spriteHref }" /> </svg> - <gl-icon v-else :name="folderIconName" :size="size" class="folder-icon" /> + <gl-icon + v-else + :name="folderIconName" + :size="size" + class="folder-icon" + data-qa-selector="folder_icon_content" + /> </span> </template> diff --git a/app/assets/javascripts/vue_shared/components/file_row.vue b/app/assets/javascripts/vue_shared/components/file_row.vue index 96567111bbc..0b0a416b7ef 100644 --- a/app/assets/javascripts/vue_shared/components/file_row.vue +++ b/app/assets/javascripts/vue_shared/components/file_row.vue @@ -1,8 +1,8 @@ <script> import { GlTruncate } from '@gitlab/ui'; -import FileHeader from '~/vue_shared/components/file_row_header.vue'; -import FileIcon from '~/vue_shared/components/file_icon.vue'; import { escapeFileUrl } from '~/lib/utils/url_utility'; +import FileIcon from '~/vue_shared/components/file_icon.vue'; +import FileHeader from '~/vue_shared/components/file_row_header.vue'; export default { name: 'FileRow', @@ -147,6 +147,7 @@ export default { :style="levelIndentation" class="file-row-name" data-qa-selector="file_name_content" + :data-qa-file-name="file.name" data-testid="file-row-name-container" :class="[fileClasses, { 'str-truncated': !truncateMiddle, 'gl-min-w-0': truncateMiddle }]" > diff --git a/app/assets/javascripts/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue b/app/assets/javascripts/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue index a4c5ca28494..97a8f681faf 100644 --- a/app/assets/javascripts/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue +++ b/app/assets/javascripts/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue @@ -10,14 +10,13 @@ import { } from '@gitlab/ui'; import RecentSearchesStorageKeys from 'ee_else_ce/filtered_search/recent_searches_storage_keys'; -import { __ } from '~/locale'; -import { deprecatedCreateFlash as createFlash } from '~/flash'; - -import RecentSearchesStore from '~/filtered_search/stores/recent_searches_store'; import RecentSearchesService from '~/filtered_search/services/recent_searches_service'; +import RecentSearchesStore from '~/filtered_search/stores/recent_searches_store'; +import { deprecatedCreateFlash as createFlash } from '~/flash'; +import { __ } from '~/locale'; -import { stripQuotes, uniqueTokens } from './filtered_search_utils'; import { SortDirection } from './constants'; +import { stripQuotes, uniqueTokens } from './filtered_search_utils'; export default { components: { diff --git a/app/assets/javascripts/vue_shared/components/filtered_search_bar/store/modules/filters/actions.js b/app/assets/javascripts/vue_shared/components/filtered_search_bar/store/modules/filters/actions.js index 411654d15f4..4dfc61f1fff 100644 --- a/app/assets/javascripts/vue_shared/components/filtered_search_bar/store/modules/filters/actions.js +++ b/app/assets/javascripts/vue_shared/components/filtered_search_bar/store/modules/filters/actions.js @@ -1,7 +1,7 @@ +import Api from '~/api'; import { deprecatedCreateFlash as createFlash } from '~/flash'; import axios from '~/lib/utils/axios_utils'; import { __ } from '~/locale'; -import Api from '~/api'; import * as types from './mutation_types'; export const setEndpoints = ({ commit }, params) => { diff --git a/app/assets/javascripts/vue_shared/components/filtered_search_bar/store/modules/filters/index.js b/app/assets/javascripts/vue_shared/components/filtered_search_bar/store/modules/filters/index.js index 665bb29a17e..cdcbecdd313 100644 --- a/app/assets/javascripts/vue_shared/components/filtered_search_bar/store/modules/filters/index.js +++ b/app/assets/javascripts/vue_shared/components/filtered_search_bar/store/modules/filters/index.js @@ -1,6 +1,6 @@ -import state from './state'; import * as actions from './actions'; import mutations from './mutations'; +import state from './state'; export default { namespaced: true, diff --git a/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/label_token.vue b/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/label_token.vue index d59e9200e6c..9c2a644b7a9 100644 --- a/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/label_token.vue +++ b/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/label_token.vue @@ -9,12 +9,11 @@ import { import { debounce } from 'lodash'; import { deprecatedCreateFlash as createFlash } from '~/flash'; -import { __ } from '~/locale'; - import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; +import { __ } from '~/locale'; -import { stripQuotes } from '../filtered_search_utils'; import { DEFAULT_LABELS, DEBOUNCE_DELAY } from '../constants'; +import { stripQuotes } from '../filtered_search_utils'; export default { components: { diff --git a/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/milestone_token.vue b/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/milestone_token.vue index 0dd7820073a..cda6e4d6726 100644 --- a/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/milestone_token.vue +++ b/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/milestone_token.vue @@ -10,8 +10,8 @@ import { debounce } from 'lodash'; import createFlash from '~/flash'; import { __ } from '~/locale'; -import { stripQuotes } from '../filtered_search_utils'; import { DEFAULT_MILESTONES, DEBOUNCE_DELAY } from '../constants'; +import { stripQuotes } from '../filtered_search_utils'; export default { components: { diff --git a/app/assets/javascripts/vue_shared/components/gfm_autocomplete/utils.js b/app/assets/javascripts/vue_shared/components/gfm_autocomplete/utils.js index 809932b0f29..44c3fc34ba6 100644 --- a/app/assets/javascripts/vue_shared/components/gfm_autocomplete/utils.js +++ b/app/assets/javascripts/vue_shared/components/gfm_autocomplete/utils.js @@ -84,7 +84,7 @@ export const tributeConfig = { value.type === groupType ? last(value.name.split(' / ')) : `${value.name}${value.username}`, menuItemLimit: memberLimit, menuItemTemplate: ({ original }) => { - const commonClasses = 'gl-avatar gl-avatar-s24 gl-flex-shrink-0'; + const commonClasses = 'gl-avatar gl-avatar-s32 gl-flex-shrink-0'; const noAvatarClasses = `${commonClasses} gl-rounded-small gl-display-flex gl-align-items-center gl-justify-content-center`; @@ -111,7 +111,7 @@ export const tributeConfig = { return ` <div class="gl-display-flex gl-align-items-center"> ${avatar} - <div class="gl-font-sm gl-line-height-normal gl-ml-3"> + <div class="gl-line-height-normal gl-ml-4"> <div>${escape(displayName)}${count}</div> <div class="gl-text-gray-700">${escape(parentGroupOrUsername)}</div> </div> diff --git a/app/assets/javascripts/vue_shared/components/gl_modal_vuex.vue b/app/assets/javascripts/vue_shared/components/gl_modal_vuex.vue index e14f6a04d3c..96d99faa952 100644 --- a/app/assets/javascripts/vue_shared/components/gl_modal_vuex.vue +++ b/app/assets/javascripts/vue_shared/components/gl_modal_vuex.vue @@ -1,6 +1,7 @@ <script> -import { mapState, mapActions } from 'vuex'; import { GlModal } from '@gitlab/ui'; +import { mapState, mapActions } from 'vuex'; +import { BV_SHOW_MODAL, BV_HIDE_MODAL } from '~/lib/utils/constants'; /** * This component keeps the GlModal's visibility in sync with the given vuex module. @@ -46,11 +47,11 @@ export default { }, }), bsShow() { - this.$root.$emit('bv::show::modal', this.modalId); + this.$root.$emit(BV_SHOW_MODAL, this.modalId); }, bsHide() { // $root.$emit is a workaround because other b-modal approaches don't work yet with gl-modal - this.$root.$emit('bv::hide::modal', this.modalId); + this.$root.$emit(BV_HIDE_MODAL, this.modalId); }, cancel() { this.$emit('cancel'); diff --git a/app/assets/javascripts/vue_shared/components/header_ci_component.vue b/app/assets/javascripts/vue_shared/components/header_ci_component.vue index 79d9ba6df57..80ca62a0e9b 100644 --- a/app/assets/javascripts/vue_shared/components/header_ci_component.vue +++ b/app/assets/javascripts/vue_shared/components/header_ci_component.vue @@ -1,11 +1,11 @@ <script> /* eslint-disable vue/no-v-html */ import { GlTooltipDirective, GlLink, GlButton, GlTooltip } from '@gitlab/ui'; +import { glEmojiTag } from '../../emoji'; +import { __, sprintf } from '../../locale'; import CiIconBadge from './ci_badge_link.vue'; import TimeagoTooltip from './time_ago_tooltip.vue'; import UserAvatarImage from './user_avatar/user_avatar_image.vue'; -import { glEmojiTag } from '../../emoji'; -import { __, sprintf } from '../../locale'; /** * Renders header component for job and pipeline page based on UI mockups @@ -105,7 +105,7 @@ export default { <section class="header-main-content"> <ci-icon-badge :status="status" /> - <strong> {{ itemName }} #{{ itemId }} </strong> + <strong data-testid="ci-header-item-text"> {{ itemName }} #{{ itemId }} </strong> <template v-if="shouldRenderTriggeredLabel">{{ __('triggered') }}</template> <template v-else>{{ __('created') }}</template> @@ -142,13 +142,13 @@ export default { </template> </section> - <section v-if="$slots.default" data-testid="headerButtons" class="gl-display-flex"> + <section v-if="$slots.default" data-testid="ci-header-action-buttons" class="gl-display-flex"> <slot></slot> </section> <gl-button v-if="hasSidebarButton" class="d-sm-none js-sidebar-build-toggle gl-ml-auto" - icon="angle-double-left" + icon="chevron-double-lg-left" :aria-label="__('Toggle sidebar')" @click="onClickSidebarButton" /> diff --git a/app/assets/javascripts/vue_shared/components/help_popover.vue b/app/assets/javascripts/vue_shared/components/help_popover.vue index 821ae6cec52..051c65bae70 100644 --- a/app/assets/javascripts/vue_shared/components/help_popover.vue +++ b/app/assets/javascripts/vue_shared/components/help_popover.vue @@ -1,8 +1,5 @@ <script> -import $ from 'jquery'; -import { GlButton } from '@gitlab/ui'; -import { inserted } from '~/feature_highlight/feature_highlight_helper'; -import { mouseenter, debouncedMouseleave, togglePopover } from '~/shared/popover'; +import { GlButton, GlPopover } from '@gitlab/ui'; /** * Render a button with a question mark icon @@ -12,6 +9,7 @@ export default { name: 'HelpPopover', components: { GlButton, + GlPopover, }, props: { options: { @@ -20,28 +18,20 @@ export default { default: () => ({}), }, }, - mounted() { - const $el = $(this.$el); - - $el - .popover({ - html: true, - trigger: 'focus', - container: 'body', - placement: 'top', - template: - '<div class="popover" role="tooltip"><div class="arrow"></div><p class="popover-header"></p><div class="popover-body"></div></div>', - ...this.options, - }) - .on('mouseenter', mouseenter) - .on('mouseleave', debouncedMouseleave(300)) - .on('inserted.bs.popover', inserted) - .on('show.bs.popover', () => { - window.addEventListener('scroll', togglePopover.bind($el, false), { once: true }); - }); - }, }; </script> <template> - <gl-button variant="link" icon="question" tabindex="0" /> + <span> + <gl-button ref="popoverTrigger" variant="link" icon="question" tabindex="0" /> + <gl-popover triggers="hover focus" :target="() => $refs.popoverTrigger.$el" v-bind="options"> + <template #title> + <!-- eslint-disable-next-line vue/no-v-html --> + <span v-html="options.title"></span> + </template> + <template #default> + <!-- eslint-disable-next-line vue/no-v-html --> + <div v-html="options.content"></div> + </template> + </gl-popover> + </span> </template> diff --git a/app/assets/javascripts/vue_shared/components/issuable/issuable_header_warnings.vue b/app/assets/javascripts/vue_shared/components/issuable/issuable_header_warnings.vue index 37995b434c4..56adbe8c606 100644 --- a/app/assets/javascripts/vue_shared/components/issuable/issuable_header_warnings.vue +++ b/app/assets/javascripts/vue_shared/components/issuable/issuable_header_warnings.vue @@ -1,6 +1,6 @@ <script> -import { mapGetters } from 'vuex'; import { GlIcon } from '@gitlab/ui'; +import { mapGetters } from 'vuex'; export default { components: { diff --git a/app/assets/javascripts/vue_shared/components/issue/issue_milestone.vue b/app/assets/javascripts/vue_shared/components/issue/issue_milestone.vue index c745ea61f8b..6a0c21602bd 100644 --- a/app/assets/javascripts/vue_shared/components/issue/issue_milestone.vue +++ b/app/assets/javascripts/vue_shared/components/issue/issue_milestone.vue @@ -1,8 +1,8 @@ <script> import { GlTooltip, GlIcon } from '@gitlab/ui'; +import { timeFor, parsePikadayDate, dateInWords } from '~/lib/utils/datetime_utility'; import { __, sprintf } from '~/locale'; import timeagoMixin from '~/vue_shared/mixins/timeago'; -import { timeFor, parsePikadayDate, dateInWords } from '~/lib/utils/datetime_utility'; export default { components: { diff --git a/app/assets/javascripts/vue_shared/components/issue/related_issuable_item.vue b/app/assets/javascripts/vue_shared/components/issue/related_issuable_item.vue index 2ff4033a07e..be0c843ef00 100644 --- a/app/assets/javascripts/vue_shared/components/issue/related_issuable_item.vue +++ b/app/assets/javascripts/vue_shared/components/issue/related_issuable_item.vue @@ -2,12 +2,12 @@ /* eslint-disable vue/no-v-html */ import '~/commons/bootstrap'; import { GlIcon, GlTooltip, GlTooltipDirective, GlButton } from '@gitlab/ui'; -import { sprintf } from '~/locale'; -import IssueMilestone from './issue_milestone.vue'; -import IssueAssignees from './issue_assignees.vue'; import IssueDueDate from '~/boards/components/issue_due_date.vue'; +import { sprintf } from '~/locale'; import relatedIssuableMixin from '../../mixins/related_issuable_mixin'; import CiIcon from '../ci_icon.vue'; +import IssueAssignees from './issue_assignees.vue'; +import IssueMilestone from './issue_milestone.vue'; export default { name: 'IssueItem', diff --git a/app/assets/javascripts/vue_shared/components/markdown/field.vue b/app/assets/javascripts/vue_shared/components/markdown/field.vue index b6e167524aa..25d01dc550f 100644 --- a/app/assets/javascripts/vue_shared/components/markdown/field.vue +++ b/app/assets/javascripts/vue_shared/components/markdown/field.vue @@ -1,19 +1,19 @@ <script> /* eslint-disable vue/no-v-html */ +import { GlIcon } from '@gitlab/ui'; import $ from 'jquery'; import '~/behaviors/markdown/render_gfm'; import { unescape } from 'lodash'; -import { GlIcon } from '@gitlab/ui'; -import { __, sprintf } from '~/locale'; -import { stripHtml } from '~/lib/utils/text_utility'; import { deprecatedCreateFlash as Flash } from '~/flash'; import GLForm from '~/gl_form'; -import MarkdownHeader from './header.vue'; -import MarkdownToolbar from './toolbar.vue'; +import axios from '~/lib/utils/axios_utils'; +import { stripHtml } from '~/lib/utils/text_utility'; +import { __, sprintf } from '~/locale'; import GfmAutocomplete from '~/vue_shared/components/gfm_autocomplete/gfm_autocomplete.vue'; import Suggestions from '~/vue_shared/components/markdown/suggestions.vue'; import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; -import axios from '~/lib/utils/axios_utils'; +import MarkdownHeader from './header.vue'; +import MarkdownToolbar from './toolbar.vue'; export default { components: { @@ -110,11 +110,6 @@ export default { return this.referencedUsers.length >= referencedUsersThreshold; }, lineContent() { - const [firstSuggestion] = this.suggestions; - if (firstSuggestion) { - return firstSuggestion.from_content; - } - if (this.line) { const { rich_text: richText, text } = this.line; diff --git a/app/assets/javascripts/vue_shared/components/markdown/header.vue b/app/assets/javascripts/vue_shared/components/markdown/header.vue index 173d192dab0..5bc1786d692 100644 --- a/app/assets/javascripts/vue_shared/components/markdown/header.vue +++ b/app/assets/javascripts/vue_shared/components/markdown/header.vue @@ -1,8 +1,8 @@ <script> -import $ from 'jquery'; import { GlPopover, GlButton, GlTooltipDirective, GlIcon } from '@gitlab/ui'; -import { s__ } from '~/locale'; +import $ from 'jquery'; import { getSelectedFragment } from '~/lib/utils/common_utils'; +import { s__ } from '~/locale'; import { CopyAsGFM } from '../../../behaviors/markdown/copy_as_gfm'; import ToolbarButton from './toolbar_button.vue'; @@ -172,6 +172,7 @@ export default { :cursor-offset="4" :tag-content="lineContent" icon="doc-code" + data-qa-selector="suggestion_button" class="js-suggestion-btn" @click="handleSuggestDismissed" /> diff --git a/app/assets/javascripts/vue_shared/components/markdown/suggestion_diff.vue b/app/assets/javascripts/vue_shared/components/markdown/suggestion_diff.vue index 93a270b8a97..bcd8c02e968 100644 --- a/app/assets/javascripts/vue_shared/components/markdown/suggestion_diff.vue +++ b/app/assets/javascripts/vue_shared/components/markdown/suggestion_diff.vue @@ -1,7 +1,7 @@ <script> +import { selectDiffLines } from '../lib/utils/diff_utils'; import SuggestionDiffHeader from './suggestion_diff_header.vue'; import SuggestionDiffRow from './suggestion_diff_row.vue'; -import { selectDiffLines } from '../lib/utils/diff_utils'; export default { components: { diff --git a/app/assets/javascripts/vue_shared/components/markdown/suggestion_diff_header.vue b/app/assets/javascripts/vue_shared/components/markdown/suggestion_diff_header.vue index 63341b433e0..4c6fa71398d 100644 --- a/app/assets/javascripts/vue_shared/components/markdown/suggestion_diff_header.vue +++ b/app/assets/javascripts/vue_shared/components/markdown/suggestion_diff_header.vue @@ -88,7 +88,12 @@ export default { applySuggestion(message) { if (!this.canApply) return; this.isApplyingSingle = true; - this.$emit('apply', this.applySuggestionCallback, message); + + this.$emit( + 'apply', + this.applySuggestionCallback, + gon.features?.suggestionsCustomCommit ? message : undefined, + ); }, applySuggestionCallback() { this.isApplyingSingle = false; @@ -131,6 +136,7 @@ export default { <gl-button v-gl-tooltip.viewport="__('This also resolves all related threads')" class="btn-inverted js-apply-batch-btn btn-grouped" + data-qa-selector="apply_suggestions_batch_button" :disabled="isApplying" variant="success" @click="applySuggestionBatch" @@ -145,6 +151,7 @@ export default { <gl-button v-if="suggestionsCount > 1 && canBeBatched && !isDisableButton" class="btn-inverted js-add-to-batch-btn btn-grouped" + data-qa-selector="add_suggestion_batch_button" :disabled="isDisableButton" @click="addSuggestionToBatch" > diff --git a/app/assets/javascripts/vue_shared/components/markdown/suggestions.vue b/app/assets/javascripts/vue_shared/components/markdown/suggestions.vue index 5ee51764555..53d1cca7af3 100644 --- a/app/assets/javascripts/vue_shared/components/markdown/suggestions.vue +++ b/app/assets/javascripts/vue_shared/components/markdown/suggestions.vue @@ -1,9 +1,9 @@ <script> -import Vue from 'vue'; import { GlSafeHtmlDirective as SafeHtml } from '@gitlab/ui'; +import Vue from 'vue'; +import { deprecatedCreateFlash as Flash } from '~/flash'; import { __ } from '~/locale'; import SuggestionDiff from './suggestion_diff.vue'; -import { deprecatedCreateFlash as Flash } from '~/flash'; export default { directives: { @@ -64,6 +64,11 @@ export default { mounted() { this.renderSuggestions(); }, + beforeDestroy() { + if (this.suggestionsWatch) { + this.suggestionsWatch(); + } + }, methods: { renderSuggestions() { // swaps out suggestion(s) markdown with rich diff components @@ -108,6 +113,13 @@ export default { }, }); + // We're using `$watch` as `suggestionsCount` updates do not + // propagate to this component for some unknown reason while + // using a traditional prop watcher. + this.suggestionsWatch = this.$watch('suggestionsCount', () => { + suggestionDiff.suggestionsCount = this.suggestionsCount; + }); + suggestionDiff.$on('apply', ({ suggestionId, callback, message }) => { this.$emit('apply', { suggestionId, callback, flashContainer: this.$el, message }); }); diff --git a/app/assets/javascripts/vue_shared/components/markdown/toolbar.vue b/app/assets/javascripts/vue_shared/components/markdown/toolbar.vue index 15c5b9d6733..387b100a04f 100644 --- a/app/assets/javascripts/vue_shared/components/markdown/toolbar.vue +++ b/app/assets/javascripts/vue_shared/components/markdown/toolbar.vue @@ -60,9 +60,7 @@ export default { </div> <span v-if="canAttachFile" class="uploading-container"> <span class="uploading-progress-container hide"> - <template> - <gl-icon name="media" /> - </template> + <gl-icon name="media" /> <span class="attaching-file-message"></span> <!-- eslint-disable-next-line @gitlab/vue-require-i18n-strings --> <span class="uploading-progress">0%</span> diff --git a/app/assets/javascripts/vue_shared/components/modal_copy_button.vue b/app/assets/javascripts/vue_shared/components/modal_copy_button.vue index e3a7f144321..7b36d57dfbf 100644 --- a/app/assets/javascripts/vue_shared/components/modal_copy_button.vue +++ b/app/assets/javascripts/vue_shared/components/modal_copy_button.vue @@ -2,6 +2,7 @@ import { GlButton, GlTooltipDirective } from '@gitlab/ui'; import Clipboard from 'clipboard'; import { uniqueId } from 'lodash'; +import { BV_HIDE_TOOLTIP } from '~/lib/utils/constants'; export default { components: { @@ -76,7 +77,7 @@ export default { }); this.clipboard .on('success', (e) => { - this.$root.$emit('bv::hide::tooltip', this.id); + this.$root.$emit(BV_HIDE_TOOLTIP, this.id); this.$emit('success', e); // Clear the selection and blur the trigger so it loses its border e.clearSelection(); diff --git a/app/assets/javascripts/vue_shared/components/navigation_tabs.vue b/app/assets/javascripts/vue_shared/components/navigation_tabs.vue index 653ee7f20e9..a069d1cd756 100644 --- a/app/assets/javascripts/vue_shared/components/navigation_tabs.vue +++ b/app/assets/javascripts/vue_shared/components/navigation_tabs.vue @@ -1,6 +1,6 @@ <script> -import $ from 'jquery'; import { GlBadge, GlTabs, GlTab } from '@gitlab/ui'; +import $ from 'jquery'; /** * Given an array of tabs, renders non linked bootstrap tabs. diff --git a/app/assets/javascripts/vue_shared/components/notes/system_note.vue b/app/assets/javascripts/vue_shared/components/notes/system_note.vue index cc1203f83f0..50972a8c32c 100644 --- a/app/assets/javascripts/vue_shared/components/notes/system_note.vue +++ b/app/assets/javascripts/vue_shared/components/notes/system_note.vue @@ -18,8 +18,6 @@ * }" * /> */ -import $ from 'jquery'; -import { mapGetters, mapActions, mapState } from 'vuex'; import { GlButton, GlDeprecatedSkeletonLoading as GlSkeletonLoading, @@ -27,12 +25,14 @@ import { GlIcon, GlSafeHtmlDirective as SafeHtml, } from '@gitlab/ui'; +import $ from 'jquery'; +import { mapGetters, mapActions, mapState } from 'vuex'; import descriptionVersionHistoryMixin from 'ee_else_ce/notes/mixins/description_version_history'; +import initMRPopovers from '~/mr_popover/'; import noteHeader from '~/notes/components/note_header.vue'; import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; -import TimelineEntryItem from './timeline_entry_item.vue'; import { spriteIcon } from '../../../lib/utils/common_utils'; -import initMRPopovers from '~/mr_popover/'; +import TimelineEntryItem from './timeline_entry_item.vue'; const MAX_VISIBLE_COMMIT_LIST_COUNT = 3; diff --git a/app/assets/javascripts/vue_shared/components/paginated_table_with_search_and_tabs/paginated_table_with_search_and_tabs.vue b/app/assets/javascripts/vue_shared/components/paginated_table_with_search_and_tabs/paginated_table_with_search_and_tabs.vue index d03987bbbe0..e2591362611 100644 --- a/app/assets/javascripts/vue_shared/components/paginated_table_with_search_and_tabs/paginated_table_with_search_and_tabs.vue +++ b/app/assets/javascripts/vue_shared/components/paginated_table_with_search_and_tabs/paginated_table_with_search_and_tabs.vue @@ -1,13 +1,13 @@ <script> import { GlAlert, GlBadge, GlPagination, GlTab, GlTabs } from '@gitlab/ui'; import Api from '~/api'; -import Tracking from '~/tracking'; -import { __ } from '~/locale'; import { updateHistory, setUrlParams } from '~/lib/utils/url_utility'; -import { initialPaginationState, defaultI18n, defaultPageSize } from './constants'; -import { isAny } from './utils'; +import { __ } from '~/locale'; +import Tracking from '~/tracking'; import FilteredSearchBar from '~/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue'; import AuthorToken from '~/vue_shared/components/filtered_search_bar/tokens/author_token.vue'; +import { initialPaginationState, defaultI18n, defaultPageSize } from './constants'; +import { isAny } from './utils'; export default { defaultI18n, diff --git a/app/assets/javascripts/vue_shared/components/project_selector/project_list_item.vue b/app/assets/javascripts/vue_shared/components/project_selector/project_list_item.vue index 65bd4e4382d..ddc8bbf9b27 100644 --- a/app/assets/javascripts/vue_shared/components/project_selector/project_list_item.vue +++ b/app/assets/javascripts/vue_shared/components/project_selector/project_list_item.vue @@ -2,9 +2,9 @@ /* eslint-disable vue/no-v-html */ import { GlButton, GlIcon } from '@gitlab/ui'; import { isString } from 'lodash'; -import ProjectAvatar from '~/vue_shared/components/project_avatar/default.vue'; import highlight from '~/lib/utils/highlight'; import { truncateNamespace } from '~/lib/utils/text_utility'; +import ProjectAvatar from '~/vue_shared/components/project_avatar/default.vue'; export default { name: 'ProjectListItem', diff --git a/app/assets/javascripts/vue_shared/components/project_selector/project_selector.vue b/app/assets/javascripts/vue_shared/components/project_selector/project_selector.vue index e659e2155fb..a0c5a0559de 100644 --- a/app/assets/javascripts/vue_shared/components/project_selector/project_selector.vue +++ b/app/assets/javascripts/vue_shared/components/project_selector/project_selector.vue @@ -1,6 +1,6 @@ <script> -import { debounce } from 'lodash'; import { GlLoadingIcon, GlSearchBoxByType, GlInfiniteScroll } from '@gitlab/ui'; +import { debounce } from 'lodash'; import { __, n__, sprintf } from '~/locale'; import ProjectListItem from './project_list_item.vue'; diff --git a/app/assets/javascripts/vue_shared/components/registry/code_instruction.vue b/app/assets/javascripts/vue_shared/components/registry/code_instruction.vue index 08ee23d25bf..bc7f8a2b17a 100644 --- a/app/assets/javascripts/vue_shared/components/registry/code_instruction.vue +++ b/app/assets/javascripts/vue_shared/components/registry/code_instruction.vue @@ -1,7 +1,7 @@ <script> import { uniqueId } from 'lodash'; -import ClipboardButton from '~/vue_shared/components/clipboard_button.vue'; import Tracking from '~/tracking'; +import ClipboardButton from '~/vue_shared/components/clipboard_button.vue'; export default { name: 'CodeInstruction', diff --git a/app/assets/javascripts/vue_shared/components/registry/list_item.vue b/app/assets/javascripts/vue_shared/components/registry/list_item.vue index 8965dba3e83..9db5d6953d7 100644 --- a/app/assets/javascripts/vue_shared/components/registry/list_item.vue +++ b/app/assets/javascripts/vue_shared/components/registry/list_item.vue @@ -54,19 +54,17 @@ export default { class="gl-display-flex gl-flex-direction-column gl-border-b-solid gl-border-t-solid gl-border-t-1 gl-border-b-1" :class="optionalClasses" > - <div class="gl-display-flex gl-align-items-center gl-py-5"> + <div class="gl-display-flex gl-align-items-center gl-py-3"> <div v-if="$slots['left-action']" - class="gl-w-7 gl-display-none gl-display-sm-flex gl-justify-content-start gl-pl-2" + class="gl-w-7 gl-display-none gl-sm-display-flex gl-justify-content-start gl-pl-2" > <slot name="left-action"></slot> </div> <div class="gl-display-flex gl-xs-flex-direction-column gl-justify-content-space-between gl-align-items-stretch gl-flex-fill-1" > - <div - class="gl-display-flex gl-flex-direction-column gl-justify-content-space-between gl-xs-mb-3 gl-min-w-0 gl-flex-grow-1" - > + <div class="gl-display-flex gl-flex-direction-column gl-xs-mb-3 gl-min-w-0 gl-flex-grow-1"> <div v-if="$slots['left-primary']" class="gl-display-flex gl-align-items-center gl-text-body gl-font-weight-bold gl-min-h-6 gl-min-w-0" @@ -77,13 +75,13 @@ export default { :selected="isDetailsShown" icon="ellipsis_h" size="small" - class="gl-ml-2 gl-display-none gl-display-sm-block" + class="gl-ml-2 gl-display-none gl-sm-display-block" @click="toggleDetails" /> </div> <div v-if="$slots['left-secondary']" - class="gl-display-flex gl-align-items-center gl-text-gray-500 gl-mt-1 gl-min-h-6 gl-min-w-0 gl-flex-fill-1" + class="gl-display-flex gl-align-items-center gl-text-gray-500 gl-min-h-6 gl-min-w-0 gl-flex-fill-1" > <slot name="left-secondary"></slot> </div> @@ -99,7 +97,7 @@ export default { </div> <div v-if="$slots['right-secondary']" - class="gl-display-flex gl-align-items-center gl-mt-1 gl-min-h-6" + class="gl-display-flex gl-align-items-center gl-min-h-6" > <slot name="right-secondary"></slot> </div> @@ -107,7 +105,7 @@ export default { </div> <div v-if="$slots['right-action']" - class="gl-w-9 gl-display-none gl-display-sm-flex gl-justify-content-end gl-pr-1" + class="gl-w-9 gl-display-none gl-sm-display-flex gl-justify-content-end gl-pr-1" > <slot name="right-action"></slot> </div> diff --git a/app/assets/javascripts/vue_shared/components/registry/registry_search.vue b/app/assets/javascripts/vue_shared/components/registry/registry_search.vue new file mode 100644 index 00000000000..62453a25f62 --- /dev/null +++ b/app/assets/javascripts/vue_shared/components/registry/registry_search.vue @@ -0,0 +1,90 @@ +<script> +import { GlSorting, GlSortingItem, GlFilteredSearch } from '@gitlab/ui'; + +const ASCENDING_ORDER = 'asc'; +const DESCENDING_ORDER = 'desc'; + +export default { + components: { + GlSorting, + GlSortingItem, + GlFilteredSearch, + }, + props: { + filter: { + type: Array, + required: true, + }, + sorting: { + type: Object, + required: true, + }, + tokens: { + type: Array, + required: false, + default: () => [], + }, + sortableFields: { + type: Array, + required: true, + }, + }, + computed: { + internalFilter: { + get() { + return this.filter; + }, + set(value) { + this.$emit('filter:changed', value); + }, + }, + sortText() { + const field = this.sortableFields.find((s) => s.orderBy === this.sorting.orderBy); + return field ? field.label : ''; + }, + isSortAscending() { + return this.sorting.sort === ASCENDING_ORDER; + }, + }, + methods: { + onDirectionChange() { + const sort = this.isSortAscending ? DESCENDING_ORDER : ASCENDING_ORDER; + this.$emit('sorting:changed', { sort }); + }, + onSortItemClick(item) { + this.$emit('sorting:changed', { orderBy: item }); + }, + clearSearch() { + this.$emit('filter:changed', []); + this.$emit('filter:submit'); + }, + }, +}; +</script> + +<template> + <div class="gl-display-flex gl-p-5 gl-bg-gray-10 gl-border-solid gl-border-1 gl-border-gray-100"> + <gl-filtered-search + v-model="internalFilter" + class="gl-mr-4 gl-flex-fill-1" + :placeholder="__('Filter results')" + :available-tokens="tokens" + @submit="$emit('filter:submit')" + @clear="clearSearch" + /> + <gl-sorting + :text="sortText" + :is-ascending="isSortAscending" + @sortDirectionChange="onDirectionChange" + > + <gl-sorting-item + v-for="item in sortableFields" + ref="packageListSortItem" + :key="item.orderBy" + @click="onSortItemClick(item.orderBy)" + > + {{ item.label }} + </gl-sorting-item> + </gl-sorting> + </div> +</template> diff --git a/app/assets/javascripts/vue_shared/components/rich_content_editor/rich_content_editor.vue b/app/assets/javascripts/vue_shared/components/rich_content_editor/rich_content_editor.vue index 5d4c192c78f..8988dab85d2 100644 --- a/app/assets/javascripts/vue_shared/components/rich_content_editor/rich_content_editor.vue +++ b/app/assets/javascripts/vue_shared/components/rich_content_editor/rich_content_editor.vue @@ -2,9 +2,9 @@ import 'codemirror/lib/codemirror.css'; import '@toast-ui/editor/dist/toastui-editor.css'; +import { EDITOR_TYPES, EDITOR_HEIGHT, EDITOR_PREVIEW_STYLE, CUSTOM_EVENTS } from './constants'; import AddImageModal from './modals/add_image/add_image_modal.vue'; import InsertVideoModal from './modals/insert_video_modal.vue'; -import { EDITOR_TYPES, EDITOR_HEIGHT, EDITOR_PREVIEW_STYLE, CUSTOM_EVENTS } from './constants'; import { registerHTMLToMarkdownRenderer, diff --git a/app/assets/javascripts/vue_shared/components/rich_content_editor/services/build_custom_renderer.js b/app/assets/javascripts/vue_shared/components/rich_content_editor/services/build_custom_renderer.js index 624b5b09b38..6ffd280e005 100644 --- a/app/assets/javascripts/vue_shared/components/rich_content_editor/services/build_custom_renderer.js +++ b/app/assets/javascripts/vue_shared/components/rich_content_editor/services/build_custom_renderer.js @@ -1,12 +1,12 @@ import { union, mapValues } from 'lodash'; -import renderBlockHtml from './renderers/render_html_block'; +import renderAttributeDefinition from './renderers/render_attribute_definition'; +import renderFontAwesomeHtmlInline from './renderers/render_font_awesome_html_inline'; import renderHeading from './renderers/render_heading'; +import renderBlockHtml from './renderers/render_html_block'; import renderIdentifierInstanceText from './renderers/render_identifier_instance_text'; import renderIdentifierParagraph from './renderers/render_identifier_paragraph'; -import renderFontAwesomeHtmlInline from './renderers/render_font_awesome_html_inline'; -import renderSoftbreak from './renderers/render_softbreak'; -import renderAttributeDefinition from './renderers/render_attribute_definition'; import renderListItem from './renderers/render_list_item'; +import renderSoftbreak from './renderers/render_softbreak'; const htmlInlineRenderers = [renderFontAwesomeHtmlInline]; const htmlBlockRenderers = [renderBlockHtml]; diff --git a/app/assets/javascripts/vue_shared/components/rich_content_editor/services/editor_service.js b/app/assets/javascripts/vue_shared/components/rich_content_editor/services/editor_service.js index be78651d38d..026a4069d9b 100644 --- a/app/assets/javascripts/vue_shared/components/rich_content_editor/services/editor_service.js +++ b/app/assets/javascripts/vue_shared/components/rich_content_editor/services/editor_service.js @@ -1,9 +1,9 @@ -import Vue from 'vue'; import { defaults } from 'lodash'; +import Vue from 'vue'; +import { TOOLBAR_ITEM_CONFIGS, VIDEO_ATTRIBUTES } from '../constants'; import ToolbarItem from '../toolbar_item.vue'; -import buildHtmlToMarkdownRenderer from './build_html_to_markdown_renderer'; import buildCustomHTMLRenderer from './build_custom_renderer'; -import { TOOLBAR_ITEM_CONFIGS, VIDEO_ATTRIBUTES } from '../constants'; +import buildHtmlToMarkdownRenderer from './build_html_to_markdown_renderer'; import sanitizeHTML from './sanitize_html'; const buildWrapper = (propsData) => { diff --git a/app/assets/javascripts/vue_shared/components/rich_content_editor/services/renderers/render_html_block.js b/app/assets/javascripts/vue_shared/components/rich_content_editor/services/renderers/render_html_block.js index 30012c1123f..710b807275b 100644 --- a/app/assets/javascripts/vue_shared/components/rich_content_editor/services/renderers/render_html_block.js +++ b/app/assets/javascripts/vue_shared/components/rich_content_editor/services/renderers/render_html_block.js @@ -1,6 +1,6 @@ -import { buildUneditableHtmlAsTextTokens } from './build_uneditable_token'; -import { ALLOWED_VIDEO_ORIGINS } from '../../constants'; import { getURLOrigin } from '~/lib/utils/url_utility'; +import { ALLOWED_VIDEO_ORIGINS } from '../../constants'; +import { buildUneditableHtmlAsTextTokens } from './build_uneditable_token'; const isVideoFrame = (html) => { const parser = new DOMParser(); diff --git a/app/assets/javascripts/vue_shared/components/rich_content_editor/services/sanitize_html.js b/app/assets/javascripts/vue_shared/components/rich_content_editor/services/sanitize_html.js index cb0f1d51cb1..486d88466b7 100644 --- a/app/assets/javascripts/vue_shared/components/rich_content_editor/services/sanitize_html.js +++ b/app/assets/javascripts/vue_shared/components/rich_content_editor/services/sanitize_html.js @@ -1,6 +1,6 @@ import createSanitizer from 'dompurify'; -import { ALLOWED_VIDEO_ORIGINS } from '../constants'; import { getURLOrigin } from '~/lib/utils/url_utility'; +import { ALLOWED_VIDEO_ORIGINS } from '../constants'; const sanitizer = createSanitizer(window); const ADD_TAGS = ['iframe']; diff --git a/app/assets/javascripts/vue_shared/components/runner_instructions/constants.js b/app/assets/javascripts/vue_shared/components/runner_instructions/constants.js new file mode 100644 index 00000000000..facace0d809 --- /dev/null +++ b/app/assets/javascripts/vue_shared/components/runner_instructions/constants.js @@ -0,0 +1,18 @@ +import { s__ } from '~/locale'; + +export const PLATFORMS_WITHOUT_ARCHITECTURES = ['docker', 'kubernetes']; + +export const INSTRUCTIONS_PLATFORMS_WITHOUT_ARCHITECTURES = { + docker: { + instructions: s__( + 'Runners|To install Runner in a container follow the instructions described in the GitLab documentation', + ), + link: 'https://docs.gitlab.com/runner/install/docker.html', + }, + kubernetes: { + instructions: s__( + 'Runners|To install Runner in Kubernetes follow the instructions described in the GitLab documentation.', + ), + link: 'https://docs.gitlab.com/runner/install/kubernetes.html', + }, +}; diff --git a/app/assets/javascripts/vue_shared/components/runner_instructions/graphql/queries/get_runner_platforms.query.graphql b/app/assets/javascripts/vue_shared/components/runner_instructions/graphql/queries/get_runner_platforms.query.graphql new file mode 100644 index 00000000000..ff0626167a9 --- /dev/null +++ b/app/assets/javascripts/vue_shared/components/runner_instructions/graphql/queries/get_runner_platforms.query.graphql @@ -0,0 +1,20 @@ +query getRunnerPlatforms($projectPath: ID!, $groupPath: ID!) { + runnerPlatforms { + nodes { + name + humanReadableName + architectures { + nodes { + name + downloadLocation + } + } + } + } + project(fullPath: $projectPath) { + id + } + group(fullPath: $groupPath) { + id + } +} diff --git a/app/assets/javascripts/vue_shared/components/runner_instructions/graphql/queries/get_runner_setup.query.graphql b/app/assets/javascripts/vue_shared/components/runner_instructions/graphql/queries/get_runner_setup.query.graphql new file mode 100644 index 00000000000..643c1991807 --- /dev/null +++ b/app/assets/javascripts/vue_shared/components/runner_instructions/graphql/queries/get_runner_setup.query.graphql @@ -0,0 +1,16 @@ +query runnerSetupInstructions( + $platform: String! + $architecture: String! + $projectId: ID! + $groupId: ID! +) { + runnerSetup( + platform: $platform + architecture: $architecture + projectId: $projectId + groupId: $groupId + ) { + installInstructions + registerInstructions + } +} diff --git a/app/assets/javascripts/vue_shared/components/runner_instructions/runner_instructions.vue b/app/assets/javascripts/vue_shared/components/runner_instructions/runner_instructions.vue new file mode 100644 index 00000000000..1d6db576942 --- /dev/null +++ b/app/assets/javascripts/vue_shared/components/runner_instructions/runner_instructions.vue @@ -0,0 +1,261 @@ +<script> +import { + GlAlert, + GlButton, + GlModal, + GlModalDirective, + GlButtonGroup, + GlDropdown, + GlDropdownItem, + GlIcon, +} from '@gitlab/ui'; +import { __, s__ } from '~/locale'; +import ModalCopyButton from '~/vue_shared/components/modal_copy_button.vue'; +import { + PLATFORMS_WITHOUT_ARCHITECTURES, + INSTRUCTIONS_PLATFORMS_WITHOUT_ARCHITECTURES, +} from './constants'; +import getRunnerPlatforms from './graphql/queries/get_runner_platforms.query.graphql'; +import getRunnerSetupInstructions from './graphql/queries/get_runner_setup.query.graphql'; + +export default { + components: { + GlAlert, + GlButton, + GlButtonGroup, + GlDropdown, + GlDropdownItem, + GlModal, + GlIcon, + ModalCopyButton, + }, + directives: { + GlModalDirective, + }, + inject: { + projectPath: { + default: '', + }, + groupPath: { + default: '', + }, + }, + apollo: { + runnerPlatforms: { + query: getRunnerPlatforms, + variables() { + return { + projectPath: this.projectPath, + groupPath: this.groupPath, + }; + }, + error() { + this.showAlert = true; + }, + result({ data }) { + this.project = data?.project; + this.group = data?.group; + + this.selectPlatform(this.platforms[0].name); + }, + }, + }, + data() { + return { + showAlert: false, + selectedPlatformArchitectures: [], + selectedPlatform: { + name: '', + }, + selectedArchitecture: {}, + runnerPlatforms: {}, + instructions: {}, + project: {}, + group: {}, + }; + }, + computed: { + isPlatformSelected() { + return Object.keys(this.selectedPlatform).length > 0; + }, + instructionsEmpty() { + return Object.keys(this.instructions).length === 0; + }, + groupId() { + return this.group?.id ?? ''; + }, + projectId() { + return this.project?.id ?? ''; + }, + platforms() { + return this.runnerPlatforms?.nodes; + }, + hasArchitecureList() { + return !PLATFORMS_WITHOUT_ARCHITECTURES.includes(this.selectedPlatform?.name); + }, + instructionsWithoutArchitecture() { + return INSTRUCTIONS_PLATFORMS_WITHOUT_ARCHITECTURES[this.selectedPlatform.name]?.instructions; + }, + runnerInstallationLink() { + return INSTRUCTIONS_PLATFORMS_WITHOUT_ARCHITECTURES[this.selectedPlatform.name]?.link; + }, + }, + methods: { + selectPlatform(name) { + this.selectedPlatform = this.platforms.find((platform) => platform.name === name); + if (this.hasArchitecureList) { + this.selectedPlatformArchitectures = this.selectedPlatform?.architectures?.nodes; + [this.selectedArchitecture] = this.selectedPlatformArchitectures; + this.selectArchitecture(this.selectedArchitecture); + } + }, + selectArchitecture(architecture) { + this.selectedArchitecture = architecture; + + this.$apollo.addSmartQuery('instructions', { + variables() { + return { + platform: this.selectedPlatform.name, + architecture: this.selectedArchitecture.name, + projectId: this.projectId, + groupId: this.groupId, + }; + }, + query: getRunnerSetupInstructions, + update(data) { + return data?.runnerSetup; + }, + error() { + this.showAlert = true; + }, + }); + }, + toggleAlert(state) { + this.showAlert = state; + }, + }, + modalId: 'installation-instructions-modal', + i18n: { + installARunner: s__('Runners|Install a Runner'), + architecture: s__('Runners|Architecture'), + downloadInstallBinary: s__('Runners|Download and Install Binary'), + downloadLatestBinary: s__('Runners|Download Latest Binary'), + registerRunner: s__('Runners|Register Runner'), + method: __('Method'), + fetchError: s__('Runners|An error has occurred fetching instructions'), + instructions: s__('Runners|Show Runner installation instructions'), + copyInstructions: s__('Runners|Copy instructions'), + }, + closeButton: { + text: __('Close'), + attributes: [{ variant: 'default' }], + }, +}; +</script> +<template> + <div> + <gl-button + v-gl-modal-directive="$options.modalId" + class="gl-mt-4" + data-testid="show-modal-button" + > + {{ $options.i18n.instructions }} + </gl-button> + <gl-modal + :modal-id="$options.modalId" + :title="$options.i18n.installARunner" + :action-secondary="$options.closeButton" + > + <gl-alert v-if="showAlert" variant="danger" @dismiss="toggleAlert(false)"> + {{ $options.i18n.fetchError }} + </gl-alert> + <h5>{{ __('Environment') }}</h5> + <gl-button-group class="gl-mb-5"> + <gl-button + v-for="platform in platforms" + :key="platform.name" + data-testid="platform-button" + @click="selectPlatform(platform.name)" + > + {{ platform.humanReadableName }} + </gl-button> + </gl-button-group> + <template v-if="hasArchitecureList"> + <template v-if="isPlatformSelected"> + <h5> + {{ $options.i18n.architecture }} + </h5> + <gl-dropdown class="gl-mb-5" :text="selectedArchitecture.name"> + <gl-dropdown-item + v-for="architecture in selectedPlatformArchitectures" + :key="architecture.name" + data-testid="architecture-dropdown-item" + @click="selectArchitecture(architecture)" + > + {{ architecture.name }} + </gl-dropdown-item> + </gl-dropdown> + <div class="gl-display-flex gl-align-items-center gl-mb-5"> + <h5>{{ $options.i18n.downloadInstallBinary }}</h5> + <gl-button + class="gl-ml-auto" + :href="selectedArchitecture.downloadLocation" + download + data-testid="binary-download-button" + > + {{ $options.i18n.downloadLatestBinary }} + </gl-button> + </div> + </template> + <template v-if="!instructionsEmpty"> + <div class="gl-display-flex"> + <pre + class="gl-bg-gray gl-flex-fill-1 gl-white-space-pre-line" + data-testid="binary-instructions" + > + + {{ instructions.installInstructions }} + </pre + > + <modal-copy-button + :title="$options.i18n.copyInstructions" + :text="instructions.installInstructions" + :modal-id="$options.modalId" + css-classes="gl-align-self-start gl-ml-2 gl-mt-2" + category="tertiary" + /> + </div> + + <hr /> + <h5 class="gl-mb-5">{{ $options.i18n.registerRunner }}</h5> + <h5 class="gl-mb-5">{{ $options.i18n.method }}</h5> + <div class="gl-display-flex"> + <pre + class="gl-bg-gray gl-flex-fill-1 gl-white-space-pre-line" + data-testid="runner-instructions" + > + {{ instructions.registerInstructions }} + </pre + > + <modal-copy-button + :title="$options.i18n.copyInstructions" + :text="instructions.registerInstructions" + :modal-id="$options.modalId" + css-classes="gl-align-self-start gl-ml-2 gl-mt-2" + category="tertiary" + /> + </div> + </template> + </template> + <template v-else> + <div> + <p>{{ instructionsWithoutArchitecture }}</p> + <gl-button :href="runnerInstallationLink"> + <gl-icon name="external-link" /> + {{ s__('Runners|View installation instructions') }} + </gl-button> + </div> + </template> + </gl-modal> + </div> +</template> diff --git a/app/assets/javascripts/vue_shared/components/settings/settings_block.vue b/app/assets/javascripts/vue_shared/components/settings/settings_block.vue new file mode 100644 index 00000000000..31094b985a2 --- /dev/null +++ b/app/assets/javascripts/vue_shared/components/settings/settings_block.vue @@ -0,0 +1,45 @@ +<script> +import { GlButton } from '@gitlab/ui'; +import { __ } from '~/locale'; + +export default { + components: { GlButton }, + props: { + defaultExpanded: { + type: Boolean, + default: false, + required: false, + }, + }, + data() { + return { + sectionExpanded: false, + }; + }, + computed: { + expanded() { + return this.defaultExpanded || this.sectionExpanded; + }, + toggleText() { + return this.expanded ? __('Collapse') : __('Expand'); + }, + }, +}; +</script> + +<template> + <section class="settings no-animate" :class="{ expanded }"> + <div class="settings-header"> + <h4><slot name="title"></slot></h4> + <gl-button @click="sectionExpanded = !sectionExpanded"> + {{ toggleText }} + </gl-button> + <p> + <slot name="description"></slot> + </p> + </div> + <div class="settings-content"> + <slot></slot> + </div> + </section> +</template> diff --git a/app/assets/javascripts/vue_shared/components/sidebar/collapsed_grouped_date_picker.vue b/app/assets/javascripts/vue_shared/components/sidebar/collapsed_grouped_date_picker.vue index 80c61627b8f..a1dca65a423 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/collapsed_grouped_date_picker.vue +++ b/app/assets/javascripts/vue_shared/components/sidebar/collapsed_grouped_date_picker.vue @@ -1,7 +1,7 @@ <script> +import { dateInWords, timeFor } from '~/lib/utils/datetime_utility'; import { __ } from '~/locale'; import timeagoMixin from '~/vue_shared/mixins/timeago'; -import { dateInWords, timeFor } from '~/lib/utils/datetime_utility'; import collapsedCalendarIcon from './collapsed_calendar_icon.vue'; export default { diff --git a/app/assets/javascripts/vue_shared/components/sidebar/date_picker.vue b/app/assets/javascripts/vue_shared/components/sidebar/date_picker.vue index 6caf8bc92c2..075681de320 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/date_picker.vue +++ b/app/assets/javascripts/vue_shared/components/sidebar/date_picker.vue @@ -1,10 +1,10 @@ <script> import { GlLoadingIcon } from '@gitlab/ui'; +import { __ } from '~/locale'; +import { dateInWords } from '../../../lib/utils/datetime_utility'; import datePicker from '../pikaday.vue'; -import toggleSidebar from './toggle_sidebar.vue'; import collapsedCalendarIcon from './collapsed_calendar_icon.vue'; -import { dateInWords } from '../../../lib/utils/datetime_utility'; -import { __ } from '~/locale'; +import toggleSidebar from './toggle_sidebar.vue'; export default { name: 'SidebarDatePicker', diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select/base.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select/base.vue index 22d86ee25d1..88c4d132d61 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select/base.vue +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select/base.vue @@ -1,20 +1,19 @@ <script> -import $ from 'jquery'; import { GlLoadingIcon } from '@gitlab/ui'; -import { __ } from '~/locale'; +import $ from 'jquery'; import LabelsSelect from '~/labels_select'; +import { __ } from '~/locale'; import DropdownHiddenInput from '~/vue_shared/components/dropdown/dropdown_hidden_input.vue'; -import DropdownTitle from './dropdown_title.vue'; -import DropdownValue from './dropdown_value.vue'; -import DropdownValueCollapsed from './dropdown_value_collapsed.vue'; +import { DropdownVariant } from '../labels_select_vue/constants'; import DropdownButton from './dropdown_button.vue'; +import DropdownCreateLabel from './dropdown_create_label.vue'; +import DropdownFooter from './dropdown_footer.vue'; import DropdownHeader from './dropdown_header.vue'; import DropdownSearchInput from './dropdown_search_input.vue'; -import DropdownFooter from './dropdown_footer.vue'; -import DropdownCreateLabel from './dropdown_create_label.vue'; - -import { DropdownVariant } from '../labels_select_vue/constants'; +import DropdownTitle from './dropdown_title.vue'; +import DropdownValue from './dropdown_value.vue'; +import DropdownValueCollapsed from './dropdown_value_collapsed.vue'; export default { DropdownVariant, diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_button.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_button.vue index c65266fce5a..60111210f5d 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_button.vue +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_button.vue @@ -1,6 +1,6 @@ <script> -import { mapActions, mapGetters } from 'vuex'; import { GlButton, GlIcon } from '@gitlab/ui'; +import { mapActions, mapGetters } from 'vuex'; export default { components: { diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_contents.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_contents.vue index 267c3be5f50..e3704198ad0 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_contents.vue +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_contents.vue @@ -1,8 +1,8 @@ <script> import { mapState } from 'vuex'; -import DropdownContentsLabelsView from './dropdown_contents_labels_view.vue'; import DropdownContentsCreateView from './dropdown_contents_create_view.vue'; +import DropdownContentsLabelsView from './dropdown_contents_labels_view.vue'; export default { components: { diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_create_view.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_create_view.vue index 41308e352e3..f8cc981ba3d 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_create_view.vue +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_create_view.vue @@ -1,6 +1,6 @@ <script> -import { mapState, mapActions } from 'vuex'; import { GlTooltipDirective, GlButton, GlFormInput, GlLink, GlLoadingIcon } from '@gitlab/ui'; +import { mapState, mapActions } from 'vuex'; export default { components: { diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view.vue index a365673f7a1..6065b6c160c 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view.vue +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view.vue @@ -1,5 +1,4 @@ <script> -import { mapState, mapGetters, mapActions } from 'vuex'; import { GlIntersectionObserver, GlLoadingIcon, @@ -8,6 +7,7 @@ import { GlLink, } from '@gitlab/ui'; import fuzzaldrinPlus from 'fuzzaldrin-plus'; +import { mapState, mapGetters, mapActions } from 'vuex'; import { UP_KEY_CODE, DOWN_KEY_CODE, ENTER_KEY_CODE, ESC_KEY_CODE } from '~/lib/utils/keycodes'; diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_title.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_title.vue index 2d6a4a9758c..5d1663bc1fd 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_title.vue +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_title.vue @@ -1,6 +1,6 @@ <script> -import { mapState, mapActions } from 'vuex'; import { GlButton, GlLoadingIcon } from '@gitlab/ui'; +import { mapState, mapActions } from 'vuex'; export default { components: { diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_value.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_value.vue index a6f99289df4..f173c8db540 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_value.vue +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_value.vue @@ -1,6 +1,6 @@ <script> -import { mapState } from 'vuex'; import { GlLabel } from '@gitlab/ui'; +import { mapState } from 'vuex'; import { isScopedLabel } from '~/lib/utils/common_utils'; diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/labels_select_root.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/labels_select_root.vue index 683889b8611..93fdae19a8d 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/labels_select_root.vue +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/labels_select_root.vue @@ -7,14 +7,12 @@ import { __ } from '~/locale'; import DropdownValueCollapsed from '~/vue_shared/components/sidebar/labels_select/dropdown_value_collapsed.vue'; -import labelsSelectModule from './store'; - -import DropdownTitle from './dropdown_title.vue'; -import DropdownValue from './dropdown_value.vue'; +import { DropdownVariant } from './constants'; import DropdownButton from './dropdown_button.vue'; import DropdownContents from './dropdown_contents.vue'; - -import { DropdownVariant } from './constants'; +import DropdownTitle from './dropdown_title.vue'; +import DropdownValue from './dropdown_value.vue'; +import labelsSelectModule from './store'; Vue.use(Vuex); @@ -35,11 +33,13 @@ export default { }, allowLabelEdit: { type: Boolean, - required: true, + required: false, + default: false, }, allowLabelCreate: { type: Boolean, - required: true, + required: false, + default: false, }, allowMultiselect: { type: Boolean, @@ -48,7 +48,8 @@ export default { }, allowScopedLabels: { type: Boolean, - required: true, + required: false, + default: false, }, variant: { type: String, diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/store/actions.js b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/store/actions.js index 14b46c1c431..89f96ab916b 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/store/actions.js +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/store/actions.js @@ -1,6 +1,6 @@ import { deprecatedCreateFlash as flash } from '~/flash'; -import { __ } from '~/locale'; import axios from '~/lib/utils/axios_utils'; +import { __ } from '~/locale'; import * as types from './mutation_types'; export const setInitialState = ({ commit }, props) => commit(types.SET_INITIAL_STATE, props); diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/store/mutations.js b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/store/mutations.js index 6de436ffd13..55716e1105e 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/store/mutations.js +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/store/mutations.js @@ -1,5 +1,5 @@ -import * as types from './mutation_types'; import { DropdownVariant } from '../constants'; +import * as types from './mutation_types'; export default { [types.SET_INITIAL_STATE](state, props) { diff --git a/app/assets/javascripts/vue_shared/components/sidebar/multiselect_dropdown.vue b/app/assets/javascripts/vue_shared/components/sidebar/multiselect_dropdown.vue index c5bbe1b33fb..132abcab82b 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/multiselect_dropdown.vue +++ b/app/assets/javascripts/vue_shared/components/sidebar/multiselect_dropdown.vue @@ -20,7 +20,7 @@ export default { </script> <template> - <gl-dropdown class="show" :text="text" :header-text="headerText"> + <gl-dropdown class="show" :text="text" :header-text="headerText" @toggle="$emit('toggle')"> <slot name="search"></slot> <gl-dropdown-form> <slot name="items"></slot> diff --git a/app/assets/javascripts/vue_shared/components/sidebar/queries/getIssueParticipants.query.graphql b/app/assets/javascripts/vue_shared/components/sidebar/queries/getIssueParticipants.query.graphql deleted file mode 100644 index 612a0c02e82..00000000000 --- a/app/assets/javascripts/vue_shared/components/sidebar/queries/getIssueParticipants.query.graphql +++ /dev/null @@ -1,13 +0,0 @@ -query issueParticipants($id: IssueID!) { - issue(id: $id) { - participants { - nodes { - username - name - webUrl - avatarUrl - id - } - } - } -} diff --git a/app/assets/javascripts/vue_shared/components/sidebar/queries/get_issue_participants.query.graphql b/app/assets/javascripts/vue_shared/components/sidebar/queries/get_issue_participants.query.graphql new file mode 100644 index 00000000000..62c0b05426b --- /dev/null +++ b/app/assets/javascripts/vue_shared/components/sidebar/queries/get_issue_participants.query.graphql @@ -0,0 +1,19 @@ +#import "~/graphql_shared/fragments/user.fragment.graphql" + +query issueParticipants($fullPath: ID!, $iid: String!) { + project(fullPath: $fullPath) { + issuable: issue(iid: $iid) { + id + participants { + nodes { + ...User + } + } + assignees { + nodes { + ...User + } + } + } + } +} diff --git a/app/assets/javascripts/vue_shared/components/sidebar/queries/get_mr_participants.query.graphql b/app/assets/javascripts/vue_shared/components/sidebar/queries/get_mr_participants.query.graphql new file mode 100644 index 00000000000..a75ce85a1dc --- /dev/null +++ b/app/assets/javascripts/vue_shared/components/sidebar/queries/get_mr_participants.query.graphql @@ -0,0 +1,19 @@ +#import "~/graphql_shared/fragments/user.fragment.graphql" + +query getMrParticipants($fullPath: ID!, $iid: String!) { + project(fullPath: $fullPath) { + issuable: mergeRequest(iid: $iid) { + id + participants { + nodes { + ...User + } + } + assignees { + nodes { + ...User + } + } + } + } +} diff --git a/app/assets/javascripts/vue_shared/components/sidebar/queries/updateAssignees.mutation.graphql b/app/assets/javascripts/vue_shared/components/sidebar/queries/update_issue_assignees.mutation.graphql index 9ead95a3801..2eb9bb4b07b 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/queries/updateAssignees.mutation.graphql +++ b/app/assets/javascripts/vue_shared/components/sidebar/queries/update_issue_assignees.mutation.graphql @@ -1,15 +1,19 @@ -mutation issueSetAssignees($iid: String!, $assigneeUsernames: [String!]!, $projectPath: ID!) { +#import "~/graphql_shared/fragments/user.fragment.graphql" + +mutation issueSetAssignees($iid: String!, $assigneeUsernames: [String!]!, $fullPath: ID!) { issueSetAssignees( - input: { iid: $iid, assigneeUsernames: $assigneeUsernames, projectPath: $projectPath } + input: { iid: $iid, assigneeUsernames: $assigneeUsernames, projectPath: $fullPath } ) { issue { + id assignees { nodes { - username - id - name - webUrl - avatarUrl + ...User + } + } + participants { + nodes { + ...User } } } diff --git a/app/assets/javascripts/vue_shared/components/sidebar/queries/update_mr_assignees.mutation.graphql b/app/assets/javascripts/vue_shared/components/sidebar/queries/update_mr_assignees.mutation.graphql new file mode 100644 index 00000000000..a0f15a07692 --- /dev/null +++ b/app/assets/javascripts/vue_shared/components/sidebar/queries/update_mr_assignees.mutation.graphql @@ -0,0 +1,21 @@ +#import "~/graphql_shared/fragments/user.fragment.graphql" + +mutation mergeRequestSetAssignees($iid: String!, $assigneeUsernames: [String!]!, $fullPath: ID!) { + mergeRequestSetAssignees( + input: { iid: $iid, assigneeUsernames: $assigneeUsernames, projectPath: $fullPath } + ) { + mergeRequest { + id + assignees { + nodes { + ...User + } + } + participants { + nodes { + ...User + } + } + } + } +} diff --git a/app/assets/javascripts/vue_shared/components/split_button.vue b/app/assets/javascripts/vue_shared/components/split_button.vue index 61b317d0d1d..994fa68fb1a 100644 --- a/app/assets/javascripts/vue_shared/components/split_button.vue +++ b/app/assets/javascripts/vue_shared/components/split_button.vue @@ -1,6 +1,6 @@ <script> -import { isString } from 'lodash'; import { GlDropdown, GlDropdownDivider, GlDropdownItem } from '@gitlab/ui'; +import { isString } from 'lodash'; const isValidItem = (item) => isString(item.eventName) && isString(item.title) && isString(item.description); diff --git a/app/assets/javascripts/vue_shared/components/stacked_progress_bar.vue b/app/assets/javascripts/vue_shared/components/stacked_progress_bar.vue index 9b6d0a87374..e639a2d966b 100644 --- a/app/assets/javascripts/vue_shared/components/stacked_progress_bar.vue +++ b/app/assets/javascripts/vue_shared/components/stacked_progress_bar.vue @@ -1,7 +1,7 @@ <script> import { GlTooltipDirective } from '@gitlab/ui'; -import { __ } from '~/locale'; import { roundDownFloat } from '~/lib/utils/common_utils'; +import { __ } from '~/locale'; export default { directives: { diff --git a/app/assets/javascripts/vue_shared/components/timezone_dropdown.vue b/app/assets/javascripts/vue_shared/components/timezone_dropdown.vue index f1db26ff4fc..b9ee74d6a03 100644 --- a/app/assets/javascripts/vue_shared/components/timezone_dropdown.vue +++ b/app/assets/javascripts/vue_shared/components/timezone_dropdown.vue @@ -1,8 +1,8 @@ <script> import { GlDropdown, GlDropdownItem, GlSearchBoxByType } from '@gitlab/ui'; +import { secondsToHours } from '~/lib/utils/datetime_utility'; import { __ } from '~/locale'; import autofocusonshow from '~/vue_shared/directives/autofocusonshow'; -import { secondsToHours } from '~/lib/utils/datetime_utility'; export default { name: 'TimezoneDropdown', diff --git a/app/assets/javascripts/vue_shared/components/todo_button.vue b/app/assets/javascripts/vue_shared/components/todo_button.vue index a9d4f8403fa..935d222a1a9 100644 --- a/app/assets/javascripts/vue_shared/components/todo_button.vue +++ b/app/assets/javascripts/vue_shared/components/todo_button.vue @@ -15,7 +15,7 @@ export default { }, computed: { buttonLabel() { - return this.isTodo ? __('Mark as done') : __('Add a To Do'); + return this.isTodo ? __('Mark as done') : __('Add a to do'); }, }, }; diff --git a/app/assets/javascripts/vue_shared/components/toggle_button.vue b/app/assets/javascripts/vue_shared/components/toggle_button.vue deleted file mode 100644 index 861661d3519..00000000000 --- a/app/assets/javascripts/vue_shared/components/toggle_button.vue +++ /dev/null @@ -1,88 +0,0 @@ -<script> -import { GlLoadingIcon, GlIcon } from '@gitlab/ui'; -import { s__ } from '../../locale'; - -const ICON_ON = 'status_success_borderless'; -const ICON_OFF = 'status_failed_borderless'; -const LABEL_ON = s__('ToggleButton|Toggle Status: ON'); -const LABEL_OFF = s__('ToggleButton|Toggle Status: OFF'); - -export default { - components: { - GlIcon, - GlLoadingIcon, - }, - - model: { - prop: 'value', - event: 'change', - }, - - props: { - name: { - type: String, - required: false, - default: null, - }, - value: { - type: Boolean, - required: false, - default: null, - }, - disabledInput: { - type: Boolean, - required: false, - default: false, - }, - isLoading: { - type: Boolean, - required: false, - default: false, - }, - }, - - computed: { - toggleIcon() { - return this.value ? ICON_ON : ICON_OFF; - }, - ariaLabel() { - return this.value ? LABEL_ON : LABEL_OFF; - }, - }, - - methods: { - toggleFeature() { - if (!this.disabledInput) this.$emit('change', !this.value); - }, - }, -}; -</script> - -<template> - <label class="gl-mt-2"> - <input v-if="name" :name="name" :value="value" type="hidden" /> - <button - type="button" - role="switch" - class="project-feature-toggle" - :aria-label="ariaLabel" - :aria-checked="value" - :class="{ - 'is-checked': value, - 'gl-blue-500': value, - 'is-disabled': disabledInput, - 'is-loading': isLoading, - }" - @click.prevent="toggleFeature" - > - <gl-loading-icon class="loading-icon" /> - <span class="toggle-icon"> - <gl-icon - :size="18" - :name="toggleIcon" - :class="value ? 'gl-text-blue-500' : 'gl-text-gray-400'" - /> - </span> - </button> - </label> -</template> diff --git a/app/assets/javascripts/vue_shared/components/tooltip_on_truncate.vue b/app/assets/javascripts/vue_shared/components/tooltip_on_truncate.vue index b48dfa8b452..8aa6e29adf1 100644 --- a/app/assets/javascripts/vue_shared/components/tooltip_on_truncate.vue +++ b/app/assets/javascripts/vue_shared/components/tooltip_on_truncate.vue @@ -1,7 +1,7 @@ <script> import { isFunction } from 'lodash'; -import tooltip from '../directives/tooltip'; import { hasHorizontalOverflow } from '~/lib/utils/dom_utils'; +import tooltip from '../directives/tooltip'; export default { directives: { diff --git a/app/assets/javascripts/vue_shared/components/upload_dropzone/upload_dropzone.vue b/app/assets/javascripts/vue_shared/components/upload_dropzone/upload_dropzone.vue index 01ba2cf5c39..5a08e992084 100644 --- a/app/assets/javascripts/vue_shared/components/upload_dropzone/upload_dropzone.vue +++ b/app/assets/javascripts/vue_shared/components/upload_dropzone/upload_dropzone.vue @@ -1,8 +1,8 @@ <script> import { GlIcon, GlLink, GlSprintf } from '@gitlab/ui'; import { __ } from '~/locale'; -import { isValidImage } from './utils'; import { VALID_DATA_TRANSFER_TYPE, VALID_IMAGE_FILE_MIMETYPE } from './constants'; +import { isValidImage } from './utils'; export default { components: { diff --git a/app/assets/javascripts/vue_shared/components/user_popover/user_popover.vue b/app/assets/javascripts/vue_shared/components/user_popover/user_popover.vue index 2ab4c55d9b0..37bde089de8 100644 --- a/app/assets/javascripts/vue_shared/components/user_popover/user_popover.vue +++ b/app/assets/javascripts/vue_shared/components/user_popover/user_popover.vue @@ -6,9 +6,9 @@ import { GlDeprecatedSkeletonLoading as GlSkeletonLoading, GlIcon, } from '@gitlab/ui'; -import UserAvailabilityStatus from '~/set_status_modal/components/user_availability_status.vue'; -import UserAvatarImage from '../user_avatar/user_avatar_image.vue'; +import UserNameWithStatus from '~/sidebar/components/assignees/user_name_with_status.vue'; import { glEmojiTag } from '../../../emoji'; +import UserAvatarImage from '../user_avatar/user_avatar_image.vue'; const MAX_SKELETON_LINES = 4; @@ -26,7 +26,7 @@ export default { GlPopover, GlSkeletonLoading, UserAvatarImage, - UserAvailabilityStatus, + UserNameWithStatus, }, props: { target: { @@ -66,7 +66,7 @@ export default { ); }, availabilityStatus() { - return this.user?.status?.availability || null; + return this.user?.status?.availability || ''; }, }, }; @@ -93,11 +93,7 @@ export default { <template v-else> <div class="gl-mb-3"> <h5 class="gl-m-0"> - {{ user.name }} - <user-availability-status - v-if="availabilityStatus" - :availability="availabilityStatus" - /> + <user-name-with-status :name="user.name" :availability="availabilityStatus" /> </h5> <span class="gl-text-gray-500">@{{ user.username }}</span> </div> diff --git a/app/assets/javascripts/vue_shared/components/web_ide_link.vue b/app/assets/javascripts/vue_shared/components/web_ide_link.vue index c957876f8ab..4bd3e352fd2 100644 --- a/app/assets/javascripts/vue_shared/components/web_ide_link.vue +++ b/app/assets/javascripts/vue_shared/components/web_ide_link.vue @@ -1,8 +1,8 @@ <script> import $ from 'jquery'; import { __ } from '~/locale'; -import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue'; import ActionsButton from '~/vue_shared/components/actions_button.vue'; +import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue'; const KEY_EDIT = 'edit'; const KEY_WEB_IDE = 'webide'; |