Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-11-17 18:15:43 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-11-17 18:15:43 +0300
commit843b1e9386fbda332839d23246d0ee2382fb7f4c (patch)
tree7663f7e38aa4e018c7210a9abdfddcd83a8bcbce /app/assets/javascripts
parent2724004cd7b8fa9d179c926c62f2fd7be63c2d81 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts')
-rw-r--r--app/assets/javascripts/header.js20
-rw-r--r--app/assets/javascripts/nav/components/new_nav_toggle.vue105
-rw-r--r--app/assets/javascripts/profile/edit/components/user_avatar.vue2
-rw-r--r--app/assets/javascripts/profile/gl_crop.js36
-rw-r--r--app/assets/javascripts/profile/profile.js2
-rw-r--r--app/assets/javascripts/snippets/components/snippet_title.vue33
-rw-r--r--app/assets/javascripts/super_sidebar/components/user_menu.vue3
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/widget/widget.vue2
8 files changed, 49 insertions, 154 deletions
diff --git a/app/assets/javascripts/header.js b/app/assets/javascripts/header.js
index 095a2dc1324..7a729cc58c3 100644
--- a/app/assets/javascripts/header.js
+++ b/app/assets/javascripts/header.js
@@ -2,11 +2,9 @@
// See https://gitlab.com/groups/gitlab-org/-/epics/11875.
import Vue from 'vue';
-import NewNavToggle from '~/nav/components/new_nav_toggle.vue';
import { highCountTrim } from '~/lib/utils/text_utility';
import Tracking from '~/tracking';
import Translate from '~/vue_shared/translate';
-import { parseBoolean } from '~/lib/utils/common_utils';
/**
* Updates todo counter when todos are toggled.
@@ -121,25 +119,7 @@ export function initNavUserDropdownTracking() {
}
}
-function initNewNavToggle() {
- const el = document.querySelector('.js-new-nav-toggle');
- if (!el) return false;
-
- return new Vue({
- el,
- render(h) {
- return h(NewNavToggle, {
- props: {
- enabled: parseBoolean(el.dataset.enabled),
- endpoint: el.dataset.endpoint,
- },
- });
- },
- });
-}
-
if (!gon?.use_new_navigation) {
requestIdleCallback(initStatusTriggers);
}
requestIdleCallback(initNavUserDropdownTracking);
-requestIdleCallback(initNewNavToggle);
diff --git a/app/assets/javascripts/nav/components/new_nav_toggle.vue b/app/assets/javascripts/nav/components/new_nav_toggle.vue
deleted file mode 100644
index 4e5d6b0ce6c..00000000000
--- a/app/assets/javascripts/nav/components/new_nav_toggle.vue
+++ /dev/null
@@ -1,105 +0,0 @@
-<script>
-import { GlToggle, GlDisclosureDropdownItem } from '@gitlab/ui';
-import axios from '~/lib/utils/axios_utils';
-import { createAlert } from '~/alert';
-import { s__ } from '~/locale';
-import Tracking from '~/tracking';
-
-export default {
- i18n: {
- sectionTitle: s__('NorthstarNavigation|Navigation redesign'),
- toggleMenuItemLabel: s__('NorthstarNavigation|New navigation'),
- toggleLabel: s__('NorthstarNavigation|Toggle new navigation'),
- updateError: s__(
- 'NorthstarNavigation|Could not update the new navigation preference. Please try again later.',
- ),
- },
- components: {
- GlToggle,
- GlDisclosureDropdownItem,
- },
- props: {
- enabled: {
- type: Boolean,
- required: true,
- },
- endpoint: {
- type: String,
- required: true,
- },
- newNavigation: {
- type: Boolean,
- required: false,
- default: false,
- },
- },
- data() {
- return {
- isEnabled: this.enabled,
- };
- },
- methods: {
- toggleNav() {
- this.isEnabled = !this.isEnabled;
- this.updateAndReload();
- },
- async updateAndReload() {
- try {
- await axios.put(this.endpoint, { user: { use_new_navigation: this.isEnabled } });
-
- Tracking.event(undefined, 'click_toggle', {
- label: this.enabled ? 'disable_new_nav_beta' : 'enable_new_nav_beta',
- property: this.enabled ? 'nav_user_menu' : 'navigation_top',
- });
-
- window.location.reload();
- } catch (error) {
- createAlert({
- message: this.$options.i18n.updateError,
- error,
- });
- }
- },
- },
-};
-</script>
-
-<template>
- <gl-disclosure-dropdown-item v-if="newNavigation" @action="toggleNav">
- <div class="gl-new-dropdown-item-content">
- <div
- class="gl-new-dropdown-item-text-wrapper gl-display-flex! gl-justify-content-space-between gl-align-items-center gl-py-2! gl-gap-3"
- >
- {{ $options.i18n.toggleMenuItemLabel }}
- <gl-toggle
- class="gl-flex-grow-0!"
- :value="isEnabled"
- :label="$options.i18n.toggleLabel"
- label-position="hidden"
- />
- </div>
- </div>
- </gl-disclosure-dropdown-item>
-
- <li v-else>
- <div
- class="gl-px-4 gl-py-2 gl-display-flex gl-justify-content-space-between gl-align-items-center"
- >
- <b>{{ $options.i18n.sectionTitle }}</b>
- </div>
-
- <div
- class="menu-item gl-cursor-pointer gl-display-flex! gl-justify-content-space-between gl-align-items-center gl-gap-3"
- @click.prevent.stop="toggleNav"
- >
- {{ $options.i18n.toggleMenuItemLabel }}
- <gl-toggle
- class="gl-flex-grow-0!"
- :value="isEnabled"
- :label="$options.i18n.toggleLabel"
- label-position="hidden"
- data-testid="new_navigation_toggle"
- />
- </div>
- </li>
-</template>
diff --git a/app/assets/javascripts/profile/edit/components/user_avatar.vue b/app/assets/javascripts/profile/edit/components/user_avatar.vue
index f0ff972336b..d69db9f3d6c 100644
--- a/app/assets/javascripts/profile/edit/components/user_avatar.vue
+++ b/app/assets/javascripts/profile/edit/components/user_avatar.vue
@@ -50,7 +50,7 @@ export default {
modalCrop: '.modal-profile-crop',
pickImageEl: '.js-choose-user-avatar-button',
uploadImageBtn: '.js-upload-user-avatar',
- modalCropImg: '.modal-profile-crop-image',
+ modalCropImg: document.querySelector('.modal-profile-crop-image'),
onBlobChange: this.onBlobChange,
};
// This has to be used with jQuery, considering migrate that from jQuery to Vue in the future.
diff --git a/app/assets/javascripts/profile/gl_crop.js b/app/assets/javascripts/profile/gl_crop.js
index ea1a5199ece..0c57dc3cbbe 100644
--- a/app/assets/javascripts/profile/gl_crop.js
+++ b/app/assets/javascripts/profile/gl_crop.js
@@ -1,7 +1,7 @@
-/* eslint-disable no-useless-escape, no-underscore-dangle, func-names, no-return-assign, consistent-return, class-methods-use-this */
+/* eslint-disable no-underscore-dangle, func-names */
import $ from 'jquery';
-import 'cropper';
+import Cropper from 'cropperjs';
import { isString } from 'lodash';
import { s__ } from '~/locale';
import { createAlert } from '~/alert';
@@ -9,7 +9,7 @@ import { loadCSSFile } from '../lib/utils/css_utils';
(() => {
// Matches everything but the file name
- const FILENAMEREGEX = /^.*[\\\/]/;
+ const FILENAMEREGEX = /^.*[\\/]/;
class GitLabCrop {
constructor(
@@ -33,7 +33,6 @@ import { loadCSSFile } from '../lib/utils/css_utils';
this.onModalShow = this.onModalShow.bind(this);
this.onPickImageClick = this.onPickImageClick.bind(this);
this.fileInput = $(input);
- this.modalCropImg = isString(this.modalCropImg) ? $(this.modalCropImg) : this.modalCropImg;
this.fileInput
.attr('name', `${this.fileInput.attr('name')}-trigger`)
.attr('id', `${this.fileInput.attr('id')}-trigger`);
@@ -53,9 +52,9 @@ import { loadCSSFile } from '../lib/utils/css_utils';
this.pickImageEl = this.getElement(pickImageEl);
this.modalCrop = isString(modalCrop) ? $(modalCrop) : modalCrop;
this.uploadImageBtn = isString(uploadImageBtn) ? $(uploadImageBtn) : uploadImageBtn;
- this.modalCropImg = isString(modalCropImg) ? $(modalCropImg) : modalCropImg;
this.cropActionsBtn = this.modalCrop.find('[data-method]');
this.onBlobChange = onBlobChange;
+ this.cropperInstance = null;
this.bindEvents();
}
@@ -78,7 +77,8 @@ import { loadCSSFile } from '../lib/utils/css_utils';
return _this.onActionBtnClick(btn);
});
this.onBlobChange(null);
- return (this.croppedImageBlob = null);
+ this.croppedImageBlob = null;
+ return null;
}
onPickImageClick() {
@@ -87,7 +87,7 @@ import { loadCSSFile } from '../lib/utils/css_utils';
onModalShow() {
const _this = this;
- return this.modalCropImg.cropper({
+ this.cropperInstance = new Cropper(this.modalCropImg, {
viewMode: 1,
center: false,
aspectRatio: 1,
@@ -104,11 +104,10 @@ import { loadCSSFile } from '../lib/utils/css_utils';
cropBoxResizable: false,
toggleDragModeOnDblclick: false,
built() {
- const $image = $(this);
- const container = $image.cropper('getContainerData');
+ const container = this.cropperInstance.getContainerData();
const { cropBoxWidth, cropBoxHeight } = _this;
- return $image.cropper('setCropBoxData', {
+ return this.cropperInstance.setCropBoxData({
width: cropBoxWidth,
height: cropBoxHeight,
left: (container.width - cropBoxWidth) / 2,
@@ -119,7 +118,7 @@ import { loadCSSFile } from '../lib/utils/css_utils';
}
onModalHide() {
- this.modalCropImg.attr('src', '').cropper('destroy');
+ this.cropperInstance.destroy();
const modalElement = document.querySelector('.modal-profile-crop');
if (modalElement) modalElement.remove();
}
@@ -134,9 +133,10 @@ import { loadCSSFile } from '../lib/utils/css_utils';
onActionBtnClick(btn) {
const data = $(btn).data();
- if (this.modalCropImg.data('cropper') && data.method) {
- return this.modalCropImg.cropper(data.method, data.option);
+ if (data.method) {
+ return this.cropperInstance[data.method](data.option);
}
+ return null;
}
onFileInputChange(e, input) {
@@ -146,7 +146,7 @@ import { loadCSSFile } from '../lib/utils/css_utils';
readFile(input) {
const reader = new FileReader();
reader.onload = () => {
- this.modalCropImg.attr('src', reader.result);
+ this.modalCropImg.setAttribute('src', reader.result);
import(/* webpackChunkName: 'bootstrapModal' */ 'bootstrap/js/dist/modal')
.then(() => {
this.modalCrop.modal('show');
@@ -162,7 +162,7 @@ import { loadCSSFile } from '../lib/utils/css_utils';
return reader.readAsDataURL(input.files[0]);
}
- dataURLtoBlob(dataURL) {
+ static dataURLtoBlob(dataURL) {
let i = 0;
let len = 0;
const binary = atob(dataURL.split(',')[1]);
@@ -184,14 +184,14 @@ import { loadCSSFile } from '../lib/utils/css_utils';
}
setBlob() {
- this.dataURL = this.modalCropImg
- .cropper('getCroppedCanvas', {
+ this.dataURL = this.cropperInstance
+ .getCroppedCanvas({
width: 200,
height: 200,
})
.toDataURL('image/png');
- this.croppedImageBlob = this.dataURLtoBlob(this.dataURL);
+ this.croppedImageBlob = GitLabCrop.dataURLtoBlob(this.dataURL);
this.onBlobChange(this.croppedImageBlob);
return this.croppedImageBlob;
}
diff --git a/app/assets/javascripts/profile/profile.js b/app/assets/javascripts/profile/profile.js
index 2ccb360c7c1..4d3824f910c 100644
--- a/app/assets/javascripts/profile/profile.js
+++ b/app/assets/javascripts/profile/profile.js
@@ -23,7 +23,7 @@ export default class Profile {
modalCrop: '.modal-profile-crop',
pickImageEl: '.js-choose-user-avatar-button',
uploadImageBtn: '.js-upload-user-avatar',
- modalCropImg: '.modal-profile-crop-image',
+ modalCropImg: document.querySelector('.modal-profile-crop-image'),
};
this.avatarGlCrop = $('.js-user-avatar-input').glCrop(cropOpts).data('glcrop');
}
diff --git a/app/assets/javascripts/snippets/components/snippet_title.vue b/app/assets/javascripts/snippets/components/snippet_title.vue
index 0e4dbf55963..f345fcf291f 100644
--- a/app/assets/javascripts/snippets/components/snippet_title.vue
+++ b/app/assets/javascripts/snippets/components/snippet_title.vue
@@ -1,15 +1,24 @@
<script>
-import { GlSprintf } from '@gitlab/ui';
-
+import { GlIcon, GlTooltipDirective, GlSprintf } from '@gitlab/ui';
+import { __, s__ } from '~/locale';
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import SnippetDescription from './snippet_description_view.vue';
export default {
+ name: 'SnippetTitle',
+ i18n: {
+ hiddenTooltip: s__('Snippets|This snippet is hidden because its author has been banned'),
+ hiddenAriaLabel: __('Hidden'),
+ },
components: {
+ GlIcon,
TimeAgoTooltip,
GlSprintf,
SnippetDescription,
},
+ directives: {
+ GlTooltip: GlTooltipDirective,
+ },
props: {
snippet: {
type: Object,
@@ -20,9 +29,23 @@ export default {
</script>
<template>
<div class="snippet-header limited-header-width">
- <h2 class="snippet-title gl-mt-0 mb-3" data-testid="snippet-title-content">
- {{ snippet.title }}
- </h2>
+ <div class="gl-display-flex">
+ <span
+ v-if="snippet.hidden"
+ class="gl-bg-orange-50 gl-text-orange-600 gl-h-6 gl-w-6 border-radius-default gl-line-height-24 gl-text-center gl-mr-3 gl-mt-2"
+ >
+ <gl-icon
+ v-gl-tooltip.bottom
+ name="spam"
+ :title="$options.i18n.hiddenTooltip"
+ :aria-label="$options.i18n.hiddenAriaLabel"
+ />
+ </span>
+
+ <h2 class="snippet-title gl-mt-0 mb-3" data-testid="snippet-title-content">
+ {{ snippet.title }}
+ </h2>
+ </div>
<snippet-description v-if="snippet.description" :description="snippet.descriptionHtml" />
diff --git a/app/assets/javascripts/super_sidebar/components/user_menu.vue b/app/assets/javascripts/super_sidebar/components/user_menu.vue
index 5712b716f48..ef4ba8d9056 100644
--- a/app/assets/javascripts/super_sidebar/components/user_menu.vue
+++ b/app/assets/javascripts/super_sidebar/components/user_menu.vue
@@ -19,9 +19,6 @@ const DROPDOWN_X_OFFSET_IMPERSONATING = DROPDOWN_X_OFFSET_BASE + IMPERSONATING_O
export default {
i18n: {
- newNavigation: {
- sectionTitle: s__('NorthstarNavigation|Navigation redesign'),
- },
setStatus: s__('SetStatusModal|Set status'),
editStatus: s__('SetStatusModal|Edit status'),
editProfile: s__('CurrentUser|Edit profile'),
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/widget/widget.vue b/app/assets/javascripts/vue_merge_request_widget/components/widget/widget.vue
index 0eb50b9ff4f..3be09eef5ad 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/widget/widget.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/widget/widget.vue
@@ -19,7 +19,7 @@ import ActionButtons from './action_buttons.vue';
const WIDGET_PREFIX = 'Widget';
const MISSING_RESPONSE_HEADERS =
- 'MR Widget: raesponse object should contain status and headers object. Make sure to include that in your `fetchCollapsedData` and `fetchExpandedData` functions.';
+ 'MR Widget: response object should contain status and headers object. Make sure to include that in your `fetchCollapsedData` and `fetchExpandedData` functions.';
const LOADING_STATE_COLLAPSED = 'collapsed';
const LOADING_STATE_EXPANDED = 'expanded';