diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-12-23 18:10:19 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-12-23 18:10:19 +0000 |
commit | b8d021cb606ac86f41a0ef9dacd133a9677f8414 (patch) | |
tree | aee1c216ff06acc7e3587a9a28af95f0392734f4 /app | |
parent | 9dbca64417abbec779a219b9e0df9d289d945032 (diff) | |
download | gitlab-ce-b8d021cb606ac86f41a0ef9dacd133a9677f8414.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
42 files changed, 276 insertions, 193 deletions
diff --git a/app/assets/javascripts/alert_management/components/alert_management_table.vue b/app/assets/javascripts/alert_management/components/alert_management_table.vue index f287b425826..f49f0c52ce6 100644 --- a/app/assets/javascripts/alert_management/components/alert_management_table.vue +++ b/app/assets/javascripts/alert_management/components/alert_management_table.vue @@ -23,7 +23,7 @@ import { } from '~/vue_shared/components/paginated_table_with_search_and_tabs/constants'; import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue'; import { convertToSnakeCase } from '~/lib/utils/text_utility'; -import getAlerts from '../graphql/queries/get_alerts.query.graphql'; +import getAlerts from '~/graphql_shared/queries/get_alerts.query.graphql'; import getAlertsCountByStatus from '../graphql/queries/get_count_by_status.query.graphql'; import { ALERTS_STATUS_TABS, diff --git a/app/assets/javascripts/alert_management/components/alert_status.vue b/app/assets/javascripts/alert_management/components/alert_status.vue index 3083a85cbd9..d7c5aa26370 100644 --- a/app/assets/javascripts/alert_management/components/alert_status.vue +++ b/app/assets/javascripts/alert_management/components/alert_status.vue @@ -3,7 +3,7 @@ import { GlDropdown, GlDropdownItem } from '@gitlab/ui'; import { s__ } from '~/locale'; import Tracking from '~/tracking'; import { trackAlertStatusUpdateOptions } from '../constants'; -import updateAlertStatusMutation from '../graphql/mutations/update_alert_status.mutation.graphql'; +import updateAlertStatusMutation from '~/graphql_shared/mutations/update_alert_status.mutation.graphql'; export default { i18n: { diff --git a/app/assets/javascripts/alert_management/graphql/fragments/detail_item.fragment.graphql b/app/assets/javascripts/alert_management/graphql/fragments/detail_item.fragment.graphql index 406dfe97ce0..9a9ae369519 100644 --- a/app/assets/javascripts/alert_management/graphql/fragments/detail_item.fragment.graphql +++ b/app/assets/javascripts/alert_management/graphql/fragments/detail_item.fragment.graphql @@ -1,5 +1,5 @@ -#import "./list_item.fragment.graphql" -#import "./alert_note.fragment.graphql" +#import "~/graphql_shared/fragments/alert.fragment.graphql" +#import "~/graphql_shared/fragments/alert_note.fragment.graphql" fragment AlertDetailItem on AlertManagementAlert { ...AlertListItem diff --git a/app/assets/javascripts/alert_management/graphql/mutations/alert_set_assignees.mutation.graphql b/app/assets/javascripts/alert_management/graphql/mutations/alert_set_assignees.mutation.graphql index 5008bfa5e1b..63d952a4857 100644 --- a/app/assets/javascripts/alert_management/graphql/mutations/alert_set_assignees.mutation.graphql +++ b/app/assets/javascripts/alert_management/graphql/mutations/alert_set_assignees.mutation.graphql @@ -1,4 +1,4 @@ -#import "../fragments/alert_note.fragment.graphql" +#import "~/graphql_shared/fragments/alert_note.fragment.graphql" mutation alertSetAssignees($projectPath: ID!, $assigneeUsernames: [String!]!, $iid: String!) { alertSetAssignees( diff --git a/app/assets/javascripts/alerts_settings/components/alerts_settings_wrapper.vue b/app/assets/javascripts/alerts_settings/components/alerts_settings_wrapper.vue index a55e63c3bc0..002d09be22b 100644 --- a/app/assets/javascripts/alerts_settings/components/alerts_settings_wrapper.vue +++ b/app/assets/javascripts/alerts_settings/components/alerts_settings_wrapper.vue @@ -243,7 +243,9 @@ export default { }); }, editIntegration({ id }) { - const currentIntegration = this.integrations.list.find(integration => integration.id === id); + const currentIntegration = this.integrations.list.find( + (integration) => integration.id === id, + ); this.$apollo.mutate({ mutation: updateCurrentIntergrationMutation, variables: { diff --git a/app/assets/javascripts/behaviors/markdown/paste_markdown_table.js b/app/assets/javascripts/behaviors/markdown/paste_markdown_table.js index 278dd857ab8..46582867d05 100644 --- a/app/assets/javascripts/behaviors/markdown/paste_markdown_table.js +++ b/app/assets/javascripts/behaviors/markdown/paste_markdown_table.js @@ -1,4 +1,5 @@ -const maxColumnWidth = (rows, columnIndex) => Math.max(...rows.map(row => row[columnIndex].length)); +const maxColumnWidth = (rows, columnIndex) => + Math.max(...rows.map((row) => row[columnIndex].length)); export default class PasteMarkdownTable { constructor(clipboardData) { @@ -16,7 +17,7 @@ export default class PasteMarkdownTable { this.calculateColumnWidths(); const markdownRows = this.rows.map( - row => + (row) => // | Name | Title | Email Address | // |--------------|-------|----------------| // | Jane Atler | CEO | jane@acme.com | @@ -66,7 +67,7 @@ export default class PasteMarkdownTable { return false; } - this.rows = splitRows.map(row => row.split('\t')); + this.rows = splitRows.map((row) => row.split('\t')); this.normalizeRows(); // Check that the max number of columns in the HTML matches the number of @@ -81,10 +82,10 @@ export default class PasteMarkdownTable { // Ensure each row has the same number of columns normalizeRows() { - const rowLengths = this.rows.map(row => row.length); + const rowLengths = this.rows.map((row) => row.length); const maxLength = Math.max(...rowLengths); - this.rows.forEach(row => { + this.rows.forEach((row) => { while (row.length < maxLength) { row.push(''); } @@ -101,7 +102,7 @@ export default class PasteMarkdownTable { const textColumnCount = this.rows[0].length; let htmlColumnCount = 0; - this.doc.querySelectorAll('table tr').forEach(row => { + this.doc.querySelectorAll('table tr').forEach((row) => { htmlColumnCount = Math.max(row.cells.length, htmlColumnCount); }); diff --git a/app/assets/javascripts/boards/components/sidebar/remove_issue.vue b/app/assets/javascripts/boards/components/sidebar/remove_issue.vue index 4e5a6609042..8d65f3240c8 100644 --- a/app/assets/javascripts/boards/components/sidebar/remove_issue.vue +++ b/app/assets/javascripts/boards/components/sidebar/remove_issue.vue @@ -42,13 +42,13 @@ export default { axios.patch(this.updateUrl, data).catch(() => { Flash(__('Failed to remove issue from board, please try again.')); - lists.forEach(list => { + lists.forEach((list) => { list.addIssue(issue); }); }); // Remove from the frontend store - lists.forEach(list => { + lists.forEach((list) => { list.removeIssue(issue); }); @@ -58,9 +58,11 @@ export default { * Build the default patch request. */ buildPatchRequest(issue, lists) { - const listLabelIds = lists.map(list => list.label.id); + const listLabelIds = lists.map((list) => list.label.id); - const labelIds = issue.labels.map(label => label.id).filter(id => !listLabelIds.includes(id)); + const labelIds = issue.labels + .map((label) => label.id) + .filter((id) => !listLabelIds.includes(id)); return { label_ids: labelIds, diff --git a/app/assets/javascripts/diffs/components/diff_row.vue b/app/assets/javascripts/diffs/components/diff_row.vue index 9a43a7405c6..0b11895097e 100644 --- a/app/assets/javascripts/diffs/components/diff_row.vue +++ b/app/assets/javascripts/diffs/components/diff_row.vue @@ -115,7 +115,9 @@ export default { const table = line.closest('.diff-table'); table.classList.remove('left-side-selected', 'right-side-selected'); - const [lineClass] = ['left-side', 'right-side'].filter(name => line.classList.contains(name)); + const [lineClass] = ['left-side', 'right-side'].filter((name) => + line.classList.contains(name), + ); if (lineClass) { table.classList.add(`${lineClass}-selected`); diff --git a/app/assets/javascripts/diffs/store/getters.js b/app/assets/javascripts/diffs/store/getters.js index 7b6db0ec706..a167b6d4694 100644 --- a/app/assets/javascripts/diffs/store/getters.js +++ b/app/assets/javascripts/diffs/store/getters.js @@ -9,13 +9,13 @@ import { export * from './getters_versions_dropdowns'; -export const isParallelView = state => state.diffViewType === PARALLEL_DIFF_VIEW_TYPE; +export const isParallelView = (state) => state.diffViewType === PARALLEL_DIFF_VIEW_TYPE; -export const isInlineView = state => state.diffViewType === INLINE_DIFF_VIEW_TYPE; +export const isInlineView = (state) => state.diffViewType === INLINE_DIFF_VIEW_TYPE; -export const whichCollapsedTypes = state => { - const automatic = state.diffFiles.some(file => file.viewer?.automaticallyCollapsed); - const manual = state.diffFiles.some(file => file.viewer?.manuallyCollapsed); +export const whichCollapsedTypes = (state) => { + const automatic = state.diffFiles.some((file) => file.viewer?.automaticallyCollapsed); + const manual = state.diffFiles.some((file) => file.viewer?.manuallyCollapsed); return { any: automatic || manual, @@ -24,18 +24,18 @@ export const whichCollapsedTypes = state => { }; }; -export const commitId = state => (state.commit && state.commit.id ? state.commit.id : null); +export const commitId = (state) => (state.commit && state.commit.id ? state.commit.id : null); /** * Checks if the diff has all discussions expanded * @param {Object} diff * @returns {Boolean} */ -export const diffHasAllExpandedDiscussions = (state, getters) => diff => { +export const diffHasAllExpandedDiscussions = (state, getters) => (diff) => { const discussions = getters.getDiffFileDiscussions(diff); return ( - (discussions && discussions.length && discussions.every(discussion => discussion.expanded)) || + (discussions && discussions.length && discussions.every((discussion) => discussion.expanded)) || false ); }; @@ -45,11 +45,13 @@ export const diffHasAllExpandedDiscussions = (state, getters) => diff => { * @param {Object} diff * @returns {Boolean} */ -export const diffHasAllCollapsedDiscussions = (state, getters) => diff => { +export const diffHasAllCollapsedDiscussions = (state, getters) => (diff) => { const discussions = getters.getDiffFileDiscussions(diff); return ( - (discussions && discussions.length && discussions.every(discussion => !discussion.expanded)) || + (discussions && + discussions.length && + discussions.every((discussion) => !discussion.expanded)) || false ); }; @@ -59,9 +61,9 @@ export const diffHasAllCollapsedDiscussions = (state, getters) => diff => { * @param {Object} diff * @returns {Boolean} */ -export const diffHasExpandedDiscussions = () => diff => { - return diff[INLINE_DIFF_LINES_KEY].filter(l => l.discussions.length >= 1).some( - l => l.discussionsExpanded, +export const diffHasExpandedDiscussions = () => (diff) => { + return diff[INLINE_DIFF_LINES_KEY].filter((l) => l.discussions.length >= 1).some( + (l) => l.discussionsExpanded, ); }; @@ -70,8 +72,8 @@ export const diffHasExpandedDiscussions = () => diff => { * @param {Boolean} diff * @returns {Boolean} */ -export const diffHasDiscussions = () => diff => { - return diff[INLINE_DIFF_LINES_KEY].some(l => l.discussions.length >= 1); +export const diffHasDiscussions = () => (diff) => { + return diff[INLINE_DIFF_LINES_KEY].some((l) => l.discussions.length >= 1); }; /** @@ -79,22 +81,22 @@ export const diffHasDiscussions = () => diff => { * @param {Object} diff * @returns {Array} */ -export const getDiffFileDiscussions = (state, getters, rootState, rootGetters) => diff => +export const getDiffFileDiscussions = (state, getters, rootState, rootGetters) => (diff) => rootGetters.discussions.filter( - discussion => discussion.diff_discussion && discussion.diff_file.file_hash === diff.file_hash, + (discussion) => discussion.diff_discussion && discussion.diff_file.file_hash === diff.file_hash, ) || []; -export const getDiffFileByHash = state => fileHash => - state.diffFiles.find(file => file.file_hash === fileHash); +export const getDiffFileByHash = (state) => (fileHash) => + state.diffFiles.find((file) => file.file_hash === fileHash); -export const flatBlobsList = state => - Object.values(state.treeEntries).filter(f => f.type === 'blob'); +export const flatBlobsList = (state) => + Object.values(state.treeEntries).filter((f) => f.type === 'blob'); export const allBlobs = (state, getters) => getters.flatBlobsList.reduce((acc, file) => { const { parentPath } = file; - if (parentPath && !acc.some(f => f.path === parentPath)) { + if (parentPath && !acc.some((f) => f.path === parentPath)) { acc.push({ path: parentPath, isHeader: true, @@ -102,13 +104,13 @@ export const allBlobs = (state, getters) => }); } - acc.find(f => f.path === parentPath).tree.push(file); + acc.find((f) => f.path === parentPath).tree.push(file); return acc; }, []); -export const getCommentFormForDiffFile = state => fileHash => - state.commentForms.find(form => form.fileHash === fileHash); +export const getCommentFormForDiffFile = (state) => (fileHash) => + state.commentForms.find((form) => form.fileHash === fileHash); /** * Returns the test coverage hits for a specific line of a given file @@ -116,7 +118,7 @@ export const getCommentFormForDiffFile = state => fileHash => * @param {number} line * @returns {number} */ -export const fileLineCoverage = state => (file, line) => { +export const fileLineCoverage = (state) => (file, line) => { if (!state.coverageFiles.files) return {}; const fileCoverage = state.coverageFiles.files[file]; if (!fileCoverage) return {}; @@ -137,13 +139,13 @@ export const fileLineCoverage = state => (file, line) => { * Returns index of a currently selected diff in diffFiles * @returns {number} */ -export const currentDiffIndex = state => +export const currentDiffIndex = (state) => Math.max( 0, - state.diffFiles.findIndex(diff => diff.file_hash === state.currentDiffFileId), + state.diffFiles.findIndex((diff) => diff.file_hash === state.currentDiffFileId), ); -export const diffLines = state => (file, unifiedDiffComponents) => { +export const diffLines = (state) => (file, unifiedDiffComponents) => { if (!unifiedDiffComponents && state.diffViewType === INLINE_DIFF_VIEW_TYPE) { return null; } @@ -155,5 +157,5 @@ export const diffLines = state => (file, unifiedDiffComponents) => { }; export function fileReviews(state) { - return state.diffFiles.map(file => isFileReviewed(state.mrReviews, file)); + return state.diffFiles.map((file) => isFileReviewed(state.mrReviews, file)); } diff --git a/app/assets/javascripts/dropzone_input.js b/app/assets/javascripts/dropzone_input.js index 49f54261983..d7aacfbce60 100644 --- a/app/assets/javascripts/dropzone_input.js +++ b/app/assets/javascripts/dropzone_input.js @@ -46,7 +46,7 @@ export default function dropzoneInput(form, config = { parallelUploads: 2 }) { let uploadFile; formTextarea.wrap('<div class="div-dropzone"></div>'); - formTextarea.on('paste', event => handlePaste(event)); + formTextarea.on('paste', (event) => handlePaste(event)); // Add dropzone area to the form. const $mdArea = formTextarea.closest('.md-area'); @@ -139,7 +139,7 @@ export default function dropzoneInput(form, config = { parallelUploads: 2 }) { // removeAllFiles(true) stops uploading files (if any) // and remove them from dropzone files queue. - $cancelButton.on('click', e => { + $cancelButton.on('click', (e) => { e.preventDefault(); e.stopPropagation(); Dropzone.forElement($formDropzone.get(0)).removeAllFiles(true); @@ -149,7 +149,7 @@ export default function dropzoneInput(form, config = { parallelUploads: 2 }) { // clear dropzone files queue, change status of failed files to undefined, // and add that files to the dropzone files queue again. // addFile() adds file to dropzone files queue and upload it. - $retryLink.on('click', e => { + $retryLink.on('click', (e) => { const dropzoneInstance = Dropzone.forElement( e.target.closest('.js-main-target-form').querySelector('.div-dropzone'), ); @@ -161,7 +161,7 @@ export default function dropzoneInput(form, config = { parallelUploads: 2 }) { // uploading of files that are being uploaded at the moment. dropzoneInstance.removeAllFiles(true); - failedFiles.map(failedFile => { + failedFiles.map((failedFile) => { const file = failedFile; if (file.status === Dropzone.ERROR) { @@ -173,7 +173,7 @@ export default function dropzoneInput(form, config = { parallelUploads: 2 }) { }); }); // eslint-disable-next-line consistent-return - handlePaste = event => { + handlePaste = (event) => { const pasteEvent = event.originalEvent; const { clipboardData } = pasteEvent; if (clipboardData && clipboardData.items) { @@ -198,7 +198,7 @@ export default function dropzoneInput(form, config = { parallelUploads: 2 }) { } }; - isImage = data => { + isImage = (data) => { let i = 0; while (i < data.clipboardData.items.length) { const item = data.clipboardData.items[i]; @@ -228,7 +228,7 @@ export default function dropzoneInput(form, config = { parallelUploads: 2 }) { return formTextarea.trigger('input'); }; - addFileToForm = path => { + addFileToForm = (path) => { $(form).append(`<input type="hidden" name="files[]" value="${escape(path)}">`); }; @@ -236,7 +236,7 @@ export default function dropzoneInput(form, config = { parallelUploads: 2 }) { const closeSpinner = () => $uploadingProgressContainer.addClass('hide'); - const showError = message => { + const showError = (message) => { $uploadingErrorContainer.removeClass('hide'); $uploadingErrorMessage.html(message); }; @@ -269,15 +269,16 @@ export default function dropzoneInput(form, config = { parallelUploads: 2 }) { insertToTextArea(filename, md); closeSpinner(); }) - .catch(e => { + .catch((e) => { showError(e.response.data.message); closeSpinner(); }); }; updateAttachingMessage = (files, messageContainer) => { - const filesCount = files.filter(file => file.status === 'uploading' || file.status === 'queued') - .length; + const filesCount = files.filter( + (file) => file.status === 'uploading' || file.status === 'queued', + ).length; const attachingMessage = n__('Attaching a file', 'Attaching %d files', filesCount); messageContainer.text(`${attachingMessage} -`); diff --git a/app/assets/javascripts/feature_flags/components/strategy.vue b/app/assets/javascripts/feature_flags/components/strategy.vue index ce03248381c..9593bcf6487 100644 --- a/app/assets/javascripts/feature_flags/components/strategy.vue +++ b/app/assets/javascripts/feature_flags/components/strategy.vue @@ -83,7 +83,7 @@ export default { ); }, filteredEnvironments() { - return this.environments.filter(e => !e.shouldBeDestroyed); + return this.environments.filter((e) => !e.shouldBeDestroyed); }, isPercentUserRollout() { return this.formStrategy.name === ROLLOUT_STRATEGY_PERCENT_ROLLOUT; @@ -91,7 +91,9 @@ export default { }, methods: { addEnvironment(environment) { - const allEnvironmentsScope = this.environments.find(scope => scope.environmentScope === '*'); + const allEnvironmentsScope = this.environments.find( + (scope) => scope.environmentScope === '*', + ); if (allEnvironmentsScope) { allEnvironmentsScope.shouldBeDestroyed = true; } @@ -113,7 +115,7 @@ export default { if (isNumber(environment.id)) { Vue.set(environment, 'shouldBeDestroyed', true); } else { - this.environments = this.environments.filter(e => e !== environment); + this.environments = this.environments.filter((e) => e !== environment); } if (this.filteredEnvironments.length === 0) { this.environments.push({ environmentScope: '*' }); diff --git a/app/assets/javascripts/alert_management/graphql/fragments/list_item.fragment.graphql b/app/assets/javascripts/graphql_shared/fragments/alert.fragment.graphql index 62119177887..62119177887 100644 --- a/app/assets/javascripts/alert_management/graphql/fragments/list_item.fragment.graphql +++ b/app/assets/javascripts/graphql_shared/fragments/alert.fragment.graphql diff --git a/app/assets/javascripts/alert_management/graphql/fragments/alert_note.fragment.graphql b/app/assets/javascripts/graphql_shared/fragments/alert_note.fragment.graphql index 74b425717a0..74b425717a0 100644 --- a/app/assets/javascripts/alert_management/graphql/fragments/alert_note.fragment.graphql +++ b/app/assets/javascripts/graphql_shared/fragments/alert_note.fragment.graphql diff --git a/app/assets/javascripts/alert_management/graphql/mutations/update_alert_status.mutation.graphql b/app/assets/javascripts/graphql_shared/mutations/update_alert_status.mutation.graphql index ba1e607bc10..42dc388c9d1 100644 --- a/app/assets/javascripts/alert_management/graphql/mutations/update_alert_status.mutation.graphql +++ b/app/assets/javascripts/graphql_shared/mutations/update_alert_status.mutation.graphql @@ -1,4 +1,4 @@ -#import "../fragments/alert_note.fragment.graphql" +#import "~/graphql_shared/fragments/alert_note.fragment.graphql" mutation updateAlertStatus($projectPath: ID!, $status: AlertManagementStatus!, $iid: String!) { updateAlertStatus(input: { iid: $iid, status: $status, projectPath: $projectPath }) { diff --git a/app/assets/javascripts/alert_management/graphql/queries/get_alerts.query.graphql b/app/assets/javascripts/graphql_shared/queries/get_alerts.query.graphql index bc7e51a2e90..e94758ef60e 100644 --- a/app/assets/javascripts/alert_management/graphql/queries/get_alerts.query.graphql +++ b/app/assets/javascripts/graphql_shared/queries/get_alerts.query.graphql @@ -1,4 +1,4 @@ -#import "../fragments/list_item.fragment.graphql" +#import "~/graphql_shared/fragments/alert.fragment.graphql" query getAlerts( $projectPath: ID! diff --git a/app/assets/javascripts/ide/lib/create_diff.js b/app/assets/javascripts/ide/lib/create_diff.js index 3e915afdbcb..51d4967fb23 100644 --- a/app/assets/javascripts/ide/lib/create_diff.js +++ b/app/assets/javascripts/ide/lib/create_diff.js @@ -32,8 +32,8 @@ const filesWithChanges = ({ stagedFiles = [], changedFiles = [], entries = {} }) // We need to clean "move" actions, because we can only support 100% similarity moves at the moment. // This is because the previous file's content might not be loaded. Object.values(changes) - .filter(change => change.action === commitActionTypes.move) - .forEach(change => { + .filter((change) => change.action === commitActionTypes.move) + .forEach((change) => { const prev = changes[change.file.prevPath]; if (!prev) { @@ -51,14 +51,14 @@ const filesWithChanges = ({ stagedFiles = [], changedFiles = [], entries = {} }) // Next, we need to add deleted directories by looking at the parents Object.values(changes) - .filter(change => change.action === commitActionTypes.delete && change.file.parentPath) + .filter((change) => change.action === commitActionTypes.delete && change.file.parentPath) .forEach(({ file }) => { // Do nothing if we've already visited this directory. if (changes[file.parentPath]) { return; } - getDeletedParents(entries, file).forEach(parent => { + getDeletedParents(entries, file).forEach((parent) => { changes[parent.path] = { action: commitActionTypes.delete, file: parent }; }); }); @@ -66,13 +66,15 @@ const filesWithChanges = ({ stagedFiles = [], changedFiles = [], entries = {} }) return Object.values(changes); }; -const createDiff = state => { +const createDiff = (state) => { const changes = filesWithChanges(state); - const toDelete = changes.filter(x => x.action === commitActionTypes.delete).map(x => x.file.path); + const toDelete = changes + .filter((x) => x.action === commitActionTypes.delete) + .map((x) => x.file.path); const patch = changes - .filter(x => x.action !== commitActionTypes.delete) + .filter((x) => x.action !== commitActionTypes.delete) .map(({ file, action }) => createFileDiff(file, action)) .join(''); diff --git a/app/assets/javascripts/ide/stores/modules/pipelines/getters.js b/app/assets/javascripts/ide/stores/modules/pipelines/getters.js index eb3cc027494..051159a0fd5 100644 --- a/app/assets/javascripts/ide/stores/modules/pipelines/getters.js +++ b/app/assets/javascripts/ide/stores/modules/pipelines/getters.js @@ -1,22 +1,23 @@ import { states } from './constants'; -export const hasLatestPipeline = state => !state.isLoadingPipeline && Boolean(state.latestPipeline); +export const hasLatestPipeline = (state) => + !state.isLoadingPipeline && Boolean(state.latestPipeline); -export const pipelineFailed = state => +export const pipelineFailed = (state) => state.latestPipeline && state.latestPipeline.details.status.text === states.failed; -export const failedStages = state => +export const failedStages = (state) => state.stages - .filter(stage => stage.status.text.toLowerCase() === states.failed) - .map(stage => ({ + .filter((stage) => stage.status.text.toLowerCase() === states.failed) + .map((stage) => ({ ...stage, - jobs: stage.jobs.filter(job => job.status.text.toLowerCase() === states.failed), + jobs: stage.jobs.filter((job) => job.status.text.toLowerCase() === states.failed), })); -export const failedJobsCount = state => +export const failedJobsCount = (state) => state.stages.reduce( - (acc, stage) => acc + stage.jobs.filter(j => j.status.text === states.failed).length, + (acc, stage) => acc + stage.jobs.filter((j) => j.status.text === states.failed).length, 0, ); -export const jobsCount = state => state.stages.reduce((acc, stage) => acc + stage.jobs.length, 0); +export const jobsCount = (state) => state.stages.reduce((acc, stage) => acc + stage.jobs.length, 0); diff --git a/app/assets/javascripts/members/components/table/members_table.vue b/app/assets/javascripts/members/components/table/members_table.vue index da77e5caad2..0c79bf06d64 100644 --- a/app/assets/javascripts/members/components/table/members_table.vue +++ b/app/assets/javascripts/members/components/table/members_table.vue @@ -34,7 +34,9 @@ export default { computed: { ...mapState(['members', 'tableFields', 'tableAttrs', 'currentUserId', 'sourceId']), filteredFields() { - return FIELDS.filter(field => this.tableFields.includes(field.key) && this.showField(field)); + return FIELDS.filter( + (field) => this.tableFields.includes(field.key) && this.showField(field), + ); }, userIsLoggedIn() { return this.currentUserId !== null; @@ -56,7 +58,7 @@ export default { return false; } - return this.members.some(member => { + return this.members.some((member) => { return ( canRemove(member, this.sourceId) || canResend(member) || diff --git a/app/assets/javascripts/members/store/utils.js b/app/assets/javascripts/members/store/utils.js index 7dcd33111e8..585962be27e 100644 --- a/app/assets/javascripts/members/store/utils.js +++ b/app/assets/javascripts/members/store/utils.js @@ -1 +1,2 @@ -export const findMember = (state, memberId) => state.members.find(member => member.id === memberId); +export const findMember = (state, memberId) => + state.members.find((member) => member.id === memberId); diff --git a/app/assets/javascripts/monitoring/components/charts/anomaly.vue b/app/assets/javascripts/monitoring/components/charts/anomaly.vue index ac401c6e381..14483fe04de 100644 --- a/app/assets/javascripts/monitoring/components/charts/anomaly.vue +++ b/app/assets/javascripts/monitoring/components/charts/anomaly.vue @@ -1,4 +1,5 @@ <script> +import produce from 'immer'; import { flattenDeep, isNumber } from 'lodash'; import { GlChartSeriesLabel } from '@gitlab/ui/dist/charts'; import { roundOffFloat } from '~/lib/utils/common_utils'; @@ -84,11 +85,13 @@ export default { metricData() { const originalMetricQuery = this.graphData.metrics[0]; - const metricQuery = { ...originalMetricQuery }; - metricQuery.result[0].values = metricQuery.result[0].values.map(([x, y]) => [ - x, - y + this.yOffset, - ]); + const metricQuery = produce(originalMetricQuery, draftQuery => { + // eslint-disable-next-line no-param-reassign + draftQuery.result[0].values = draftQuery.result[0].values.map(([x, y]) => [ + x, + y + this.yOffset, + ]); + }); return { ...this.graphData, type: panelTypes.LINE_CHART, diff --git a/app/assets/javascripts/monitoring/stores/actions.js b/app/assets/javascripts/monitoring/stores/actions.js index e7391a4c9d1..44c200cdb54 100644 --- a/app/assets/javascripts/monitoring/stores/actions.js +++ b/app/assets/javascripts/monitoring/stores/actions.js @@ -114,7 +114,7 @@ export const fetchDashboard = ({ state, commit, dispatch, getters }) => { } return getDashboard(state.dashboardEndpoint, params) - .then(response => { + .then((response) => { dispatch('receiveMetricsDashboardSuccess', { response }); /** * After the dashboard is fetched, there can be non-blocking invalid syntax @@ -125,7 +125,7 @@ export const fetchDashboard = ({ state, commit, dispatch, getters }) => { */ dispatch('fetchDashboardValidationWarnings'); }) - .catch(error => { + .catch((error) => { Sentry.captureException(error); commit(types.SET_ALL_DASHBOARDS, error.response?.data?.all_dashboards ?? []); @@ -185,9 +185,9 @@ export const fetchDashboardData = ({ state, dispatch, getters }) => { dispatch('fetchVariableMetricLabelValues', { defaultQueryParams }); const promises = []; - state.dashboard.panelGroups.forEach(group => { - group.panels.forEach(panel => { - panel.metrics.forEach(metric => { + state.dashboard.panelGroups.forEach((group) => { + group.panels.forEach((panel) => { + panel.metrics.forEach((metric) => { promises.push(dispatch('fetchPrometheusMetric', { metric, defaultQueryParams })); }); }); @@ -231,10 +231,10 @@ export const fetchPrometheusMetric = ( commit(types.REQUEST_METRIC_RESULT, { metricId: metric.metricId }); return getPrometheusQueryData(metric.prometheusEndpointPath, queryParams) - .then(data => { + .then((data) => { commit(types.RECEIVE_METRIC_RESULT_SUCCESS, { metricId: metric.metricId, data }); }) - .catch(error => { + .catch((error) => { Sentry.captureException(error); commit(types.RECEIVE_METRIC_RESULT_FAILURE, { metricId: metric.metricId, error }); @@ -251,15 +251,15 @@ export const fetchDeploymentsData = ({ state, dispatch }) => { } return axios .get(state.deploymentsEndpoint) - .then(resp => resp.data) - .then(response => { + .then((resp) => resp.data) + .then((response) => { if (!response || !response.deployments) { createFlash(s__('Metrics|Unexpected deployment data response from prometheus endpoint')); } dispatch('receiveDeploymentsDataSuccess', response.deployments); }) - .catch(error => { + .catch((error) => { Sentry.captureException(error); dispatch('receiveDeploymentsDataFailure'); createFlash(s__('Metrics|There was an error getting deployment information.')); @@ -285,10 +285,10 @@ export const fetchEnvironmentsData = ({ state, dispatch }) => { states: [ENVIRONMENT_AVAILABLE_STATE], }, }) - .then(resp => + .then((resp) => parseEnvironmentsResponse(resp.data?.project?.data?.environments, state.projectPath), ) - .then(environments => { + .then((environments) => { if (!environments) { createFlash( s__('Metrics|There was an error fetching the environments data, please try again'), @@ -297,7 +297,7 @@ export const fetchEnvironmentsData = ({ state, dispatch }) => { dispatch('receiveEnvironmentsDataSuccess', environments); }) - .catch(err => { + .catch((err) => { Sentry.captureException(err); dispatch('receiveEnvironmentsDataFailure'); createFlash(s__('Metrics|There was an error getting environments information.')); @@ -326,16 +326,18 @@ export const fetchAnnotations = ({ state, dispatch, getters }) => { startingFrom: start, }, }) - .then(resp => resp.data?.project?.environments?.nodes?.[0].metricsDashboard?.annotations.nodes) + .then( + (resp) => resp.data?.project?.environments?.nodes?.[0].metricsDashboard?.annotations.nodes, + ) .then(parseAnnotationsResponse) - .then(annotations => { + .then((annotations) => { if (!annotations) { createFlash(s__('Metrics|There was an error fetching annotations. Please try again.')); } dispatch('receiveAnnotationsSuccess', annotations); }) - .catch(err => { + .catch((err) => { Sentry.captureException(err); dispatch('receiveAnnotationsFailure'); createFlash(s__('Metrics|There was an error getting annotations information.')); @@ -363,7 +365,7 @@ export const fetchDashboardValidationWarnings = ({ state, dispatch, getters }) = dashboardPath, }, }) - .then(resp => resp.data?.project?.environments?.nodes?.[0]?.metricsDashboard) + .then((resp) => resp.data?.project?.environments?.nodes?.[0]?.metricsDashboard) .then(({ schemaValidationWarnings } = {}) => { const hasWarnings = schemaValidationWarnings && schemaValidationWarnings.length !== 0; /** @@ -372,7 +374,7 @@ export const fetchDashboardValidationWarnings = ({ state, dispatch, getters }) = */ dispatch('receiveDashboardValidationWarningsSuccess', hasWarnings || false); }) - .catch(err => { + .catch((err) => { Sentry.captureException(err); dispatch('receiveDashboardValidationWarningsFailure'); createFlash( @@ -437,9 +439,9 @@ export const duplicateSystemDashboard = ({ state }, payload) => { return axios .post(state.dashboardsEndpoint, params) - .then(response => response.data) - .then(data => data.dashboard) - .catch(error => { + .then((response) => response.data) + .then((data) => data.dashboard) + .catch((error) => { Sentry.captureException(error); const { response } = error; @@ -466,7 +468,7 @@ export const fetchVariableMetricLabelValues = ({ state, commit }, { defaultQuery const { start_time, end_time } = defaultQueryParams; const optionsRequests = []; - state.variables.forEach(variable => { + state.variables.forEach((variable) => { if (variable.type === VARIABLE_TYPES.metric_label_values) { const { prometheusEndpointPath, label } = variable.options; @@ -474,7 +476,7 @@ export const fetchVariableMetricLabelValues = ({ state, commit }, { defaultQuery start_time, end_time, }) - .then(data => { + .then((data) => { commit(types.UPDATE_VARIABLE_METRIC_LABEL_VALUES, { variable, label, data }); }) .catch(() => { @@ -512,7 +514,7 @@ export const fetchPanelPreview = ({ state, commit, dispatch }, panelPreviewYml) dispatch('fetchPanelPreviewMetrics'); }) - .catch(error => { + .catch((error) => { commit(types.RECEIVE_PANEL_PREVIEW_FAILURE, extractErrorMessage(error)); }); }; @@ -535,10 +537,10 @@ export const fetchPanelPreviewMetrics = ({ state, commit }) => { return getPrometheusQueryData(metric.prometheusEndpointPath, params, { cancelToken: cancelTokenSource.token, }) - .then(data => { + .then((data) => { commit(types.RECEIVE_PANEL_PREVIEW_METRIC_RESULT_SUCCESS, { index, data }); }) - .catch(error => { + .catch((error) => { Sentry.captureException(error); commit(types.RECEIVE_PANEL_PREVIEW_METRIC_RESULT_FAILURE, { index, error }); diff --git a/app/assets/javascripts/monitoring/stores/getters.js b/app/assets/javascripts/monitoring/stores/getters.js index 8ed83cf02fe..d6a04006264 100644 --- a/app/assets/javascripts/monitoring/stores/getters.js +++ b/app/assets/javascripts/monitoring/stores/getters.js @@ -5,8 +5,10 @@ import { normalizeCustomDashboardPath, } from './utils'; -const metricsIdsInPanel = panel => - panel.metrics.filter(metric => metric.metricId && metric.result).map(metric => metric.metricId); +const metricsIdsInPanel = (panel) => + panel.metrics + .filter((metric) => metric.metricId && metric.result) + .map((metric) => metric.metricId); /** * Returns a reference to the currently selected dashboard @@ -17,8 +19,8 @@ const metricsIdsInPanel = panel => export const selectedDashboard = (state, getters) => { const { allDashboards } = state; return ( - allDashboards.find(d => d.path === getters.fullDashboardPath) || - allDashboards.find(d => d.default) || + allDashboards.find((d) => d.path === getters.fullDashboardPath) || + allDashboards.find((d) => d.default) || null ); }; @@ -32,15 +34,15 @@ export const selectedDashboard = (state, getters) => { * @returns {Function} A function that returns an array of * states in all the metric in the dashboard or group. */ -export const getMetricStates = state => groupKey => { +export const getMetricStates = (state) => (groupKey) => { let groups = state.dashboard.panelGroups; if (groupKey) { - groups = groups.filter(group => group.key === groupKey); + groups = groups.filter((group) => group.key === groupKey); } const metricStates = groups.reduce((acc, group) => { - group.panels.forEach(panel => { - panel.metrics.forEach(metric => { + group.panels.forEach((panel) => { + panel.metrics.forEach((metric) => { if (metric.state) { acc.push(metric.state); } @@ -64,15 +66,15 @@ export const getMetricStates = state => groupKey => { * metrics in the dashboard that contain results, optionally * filtered by group key. */ -export const metricsWithData = state => groupKey => { +export const metricsWithData = (state) => (groupKey) => { let groups = state.dashboard.panelGroups; if (groupKey) { - groups = groups.filter(group => group.key === groupKey); + groups = groups.filter((group) => group.key === groupKey); } const res = []; - groups.forEach(group => { - group.panels.forEach(panel => { + groups.forEach((group) => { + group.panels.forEach((panel) => { res.push(...metricsIdsInPanel(panel)); }); }); @@ -89,7 +91,7 @@ export const metricsWithData = state => groupKey => { * https://gitlab.com/gitlab-org/gitlab/-/issues/28241 * https://gitlab.com/gitlab-org/gitlab/-/merge_requests/27447 */ -export const metricsSavedToDb = state => { +export const metricsSavedToDb = (state) => { const metricIds = []; state.dashboard.panelGroups.forEach(({ panels }) => { panels.forEach(({ metrics }) => { @@ -111,8 +113,8 @@ export const metricsSavedToDb = state => { * @param {Object} state * @returns {Array} List of environments */ -export const filteredEnvironments = state => - state.environments.filter(env => +export const filteredEnvironments = (state) => + state.environments.filter((env) => env.name.toLowerCase().includes((state.environmentsSearchTerm || '').trim().toLowerCase()), ); @@ -125,7 +127,7 @@ export const filteredEnvironments = state => * @param {Object} state * @returns {Array} modified array of links */ -export const linksWithMetadata = state => { +export const linksWithMetadata = (state) => { const metadata = { timeRange: state.timeRange, }; @@ -152,7 +154,7 @@ export const linksWithMetadata = state => { * in the format of {variables[key1]=value1, variables[key2]=value2} */ -export const getCustomVariablesParams = state => +export const getCustomVariablesParams = (state) => state.variables.reduce((acc, variable) => { const { name, value } = variable; if (value !== null) { @@ -168,5 +170,5 @@ export const getCustomVariablesParams = state => * @param {Object} state * @returns {String} full dashboard path */ -export const fullDashboardPath = state => +export const fullDashboardPath = (state) => normalizeCustomDashboardPath(state.currentDashboard, state.customDashboardBasePath); diff --git a/app/assets/javascripts/packages/list/utils.js b/app/assets/javascripts/packages/list/utils.js index 6a300d7bfe6..ee89d3cdefe 100644 --- a/app/assets/javascripts/packages/list/utils.js +++ b/app/assets/javascripts/packages/list/utils.js @@ -1,6 +1,7 @@ import { LIST_KEY_PROJECT, SORT_FIELDS } from './constants'; -export default isGroupPage => SORT_FIELDS.filter(f => f.key !== LIST_KEY_PROJECT || isGroupPage); +export default (isGroupPage) => + SORT_FIELDS.filter((f) => f.key !== LIST_KEY_PROJECT || isGroupPage); /** * A small util function that works out if the delete action has deleted the diff --git a/app/assets/javascripts/pages/projects/forks/new/components/fork_groups_list.vue b/app/assets/javascripts/pages/projects/forks/new/components/fork_groups_list.vue index 6c0d20c55e9..a614443bcd9 100644 --- a/app/assets/javascripts/pages/projects/forks/new/components/fork_groups_list.vue +++ b/app/assets/javascripts/pages/projects/forks/new/components/fork_groups_list.vue @@ -31,7 +31,9 @@ export default { }, computed: { filteredNamespaces() { - return this.namespaces.filter(n => n.name.toLowerCase().includes(this.filter.toLowerCase())); + return this.namespaces.filter((n) => + n.name.toLowerCase().includes(this.filter.toLowerCase()), + ); }, }, @@ -43,7 +45,7 @@ export default { loadGroups() { axios .get(this.endpoint) - .then(response => { + .then((response) => { this.namespaces = response.data.namespaces; }) .catch(() => createFlash(__('There was a problem fetching groups.'))); diff --git a/app/assets/javascripts/pages/users/user_tabs.js b/app/assets/javascripts/pages/users/user_tabs.js index 2485853afc7..7c88aa53e4b 100644 --- a/app/assets/javascripts/pages/users/user_tabs.js +++ b/app/assets/javascripts/pages/users/user_tabs.js @@ -100,8 +100,8 @@ export default class UserTabs { bindEvents() { this.$parentEl .off('shown.bs.tab', '.nav-links a[data-toggle="tab"]') - .on('shown.bs.tab', '.nav-links a[data-toggle="tab"]', event => this.tabShown(event)) - .on('click', '.gl-pagination a', event => this.changeProjectsPage(event)); + .on('shown.bs.tab', '.nav-links a[data-toggle="tab"]', (event) => this.tabShown(event)) + .on('click', '.gl-pagination a', (event) => this.changeProjectsPage(event)); window.addEventListener('resize', () => this.onResize()); } @@ -212,17 +212,19 @@ export default class UserTabs { const calendarPath = $calendarWrap.data('calendarPath'); AjaxCache.retrieve(calendarPath) - .then(data => UserTabs.renderActivityCalendar(data, $calendarWrap)) + .then((data) => UserTabs.renderActivityCalendar(data, $calendarWrap)) .catch(() => { const cWrap = $calendarWrap[0]; cWrap.querySelector('.spinner').classList.add('invisible'); cWrap.querySelector('.user-calendar-error').classList.remove('invisible'); - cWrap.querySelector('.user-calendar-error .js-retry-load').addEventListener('click', e => { - e.preventDefault(); - cWrap.querySelector('.user-calendar-error').classList.add('invisible'); - cWrap.querySelector('.spinner').classList.remove('invisible'); - this.loadActivityCalendar(); - }); + cWrap + .querySelector('.user-calendar-error .js-retry-load') + .addEventListener('click', (e) => { + e.preventDefault(); + cWrap.querySelector('.user-calendar-error').classList.add('invisible'); + cWrap.querySelector('.spinner').classList.remove('invisible'); + this.loadActivityCalendar(); + }); }); } diff --git a/app/assets/javascripts/projects/settings/access_dropdown.js b/app/assets/javascripts/projects/settings/access_dropdown.js index cb4fd5265da..a62b5d423de 100644 --- a/app/assets/javascripts/projects/settings/access_dropdown.js +++ b/app/assets/javascripts/projects/settings/access_dropdown.js @@ -25,7 +25,7 @@ export default class AccessDropdown { this.setSelectedItems([]); this.persistPreselectedItems(); - this.noOneObj = this.accessLevelsData.find(level => level.id === ACCESS_LEVEL_NONE); + this.noOneObj = this.accessLevelsData.find((level) => level.id === ACCESS_LEVEL_NONE); this.initDropdown(); } @@ -45,7 +45,7 @@ export default class AccessDropdown { onHide(); } }, - clicked: options => { + clicked: (options) => { const { $el, e } = options; const item = options.selectedObj; const fossWithMergeAccess = !this.hasLicense && this.accessLevel === ACCESS_LEVELS.MERGE; @@ -56,7 +56,7 @@ export default class AccessDropdown { // We're not multiselecting quite yet in "Merge" access dropdown, on FOSS: // remove all preselected items before selecting this item // https://gitlab.com/gitlab-org/gitlab/-/merge_requests/37499 - this.accessLevelsData.forEach(level => { + this.accessLevelsData.forEach((level) => { this.removeSelectedItem(level); }); } @@ -65,7 +65,7 @@ export default class AccessDropdown { if (this.noOneObj) { if (item.id === this.noOneObj.id && !fossWithMergeAccess) { // remove all others selected items - this.accessLevelsData.forEach(level => { + this.accessLevelsData.forEach((level) => { if (level.id !== item.id) { this.removeSelectedItem(level); } @@ -109,7 +109,7 @@ export default class AccessDropdown { return; } - const persistedItems = itemsToPreselect.map(item => { + const persistedItems = itemsToPreselect.map((item) => { const persistedItem = { ...item }; persistedItem.persisted = true; return persistedItem; @@ -123,7 +123,7 @@ export default class AccessDropdown { } getSelectedItems() { - return this.items.filter(item => !item._destroy); + return this.items.filter((item) => !item._destroy); } getAllSelectedItems() { @@ -134,7 +134,7 @@ export default class AccessDropdown { getInputData() { const selectedItems = this.getAllSelectedItems(); - const accessLevels = selectedItems.map(item => { + const accessLevels = selectedItems.map((item) => { const obj = {}; if (typeof item.id !== 'undefined') { @@ -288,12 +288,14 @@ export default class AccessDropdown { $dropdownToggleText.removeClass('is-default'); if (currentItems.length === 1 && currentItems[0].type === LEVEL_TYPES.ROLE) { - const roleData = this.accessLevelsData.find(data => data.id === currentItems[0].access_level); + const roleData = this.accessLevelsData.find( + (data) => data.id === currentItems[0].access_level, + ); return roleData.text; } const labelPieces = []; - const counts = countBy(currentItems, item => item.type); + const counts = countBy(currentItems, (item) => item.type); if (counts[LEVEL_TYPES.ROLE] > 0) { labelPieces.push(n__('1 role', '%d roles', counts[LEVEL_TYPES.ROLE])); @@ -336,7 +338,7 @@ export default class AccessDropdown { }); } else { this.getDeployKeys(query) - .then(deployKeysResponse => callback(this.consolidateData(deployKeysResponse.data))) + .then((deployKeysResponse) => callback(this.consolidateData(deployKeysResponse.data))) .catch(() => createFlash({ message: __('Failed to load deploy keys.') })); } } @@ -365,7 +367,7 @@ export default class AccessDropdown { /* * Build roles */ - const roles = this.accessLevelsData.map(level => { + const roles = this.accessLevelsData.map((level) => { /* eslint-disable no-param-reassign */ // This re-assignment is intentional as // level.type property is being used in removeSelectedItem() @@ -389,7 +391,7 @@ export default class AccessDropdown { /* * Build groups */ - const groups = groupsResponse.map(group => ({ + const groups = groupsResponse.map((group) => ({ ...group, type: LEVEL_TYPES.GROUP, })); @@ -398,8 +400,8 @@ export default class AccessDropdown { * Build users */ const users = selectedItems - .filter(item => item.type === LEVEL_TYPES.USER) - .map(item => { + .filter((item) => item.type === LEVEL_TYPES.USER) + .map((item) => { // Save identifiers for easy-checking more later map.push(LEVEL_TYPES.USER + item.user_id); @@ -414,7 +416,7 @@ export default class AccessDropdown { // Has to be checked against server response // because the selected item can be in filter results - usersResponse.forEach(response => { + usersResponse.forEach((response) => { // Add is it has not been added if (map.indexOf(LEVEL_TYPES.USER + response.id) === -1) { const user = { ...response }; @@ -444,7 +446,7 @@ export default class AccessDropdown { } if (this.deployKeysOnProtectedBranchesEnabled) { - const deployKeys = deployKeysResponse.map(response => { + const deployKeys = deployKeysResponse.map((response) => { const { id, fingerprint, diff --git a/app/assets/javascripts/registry/explorer/components/list_page/registry_header.vue b/app/assets/javascripts/registry/explorer/components/list_page/registry_header.vue index c2bd01701df..bad804ad172 100644 --- a/app/assets/javascripts/registry/explorer/components/list_page/registry_header.vue +++ b/app/assets/javascripts/registry/explorer/components/list_page/registry_header.vue @@ -43,6 +43,11 @@ export default { required: false, default: false, }, + metadataLoading: { + type: Boolean, + required: false, + default: false, + }, }, loader: { repeat: 10, @@ -92,7 +97,11 @@ export default { </script> <template> - <title-area :title="$options.i18n.CONTAINER_REGISTRY_TITLE" :info-messages="infoMessages"> + <title-area + :title="$options.i18n.CONTAINER_REGISTRY_TITLE" + :info-messages="infoMessages" + :metadata-loading="metadataLoading" + > <template #right-actions> <slot name="commands"></slot> </template> diff --git a/app/assets/javascripts/registry/explorer/pages/list.vue b/app/assets/javascripts/registry/explorer/pages/list.vue index d4c052c02cd..270c01ea60f 100644 --- a/app/assets/javascripts/registry/explorer/pages/list.vue +++ b/app/assets/javascripts/registry/explorer/pages/list.vue @@ -242,6 +242,7 @@ export default { <template v-else> <registry-header + :metadata-loading="isLoading" :images-count="containerRepositoriesCount" :expiration-policy="config.expirationPolicy" :help-page-path="config.helpPagePath" diff --git a/app/assets/javascripts/repository/log_tree.js b/app/assets/javascripts/repository/log_tree.js index fc8fa40a855..9001bcd8fc3 100644 --- a/app/assets/javascripts/repository/log_tree.js +++ b/app/assets/javascripts/repository/log_tree.js @@ -9,7 +9,9 @@ const fetchpromises = {}; const resolvers = {}; export function resolveCommit(commits, path, { resolve, entry }) { - const commit = commits.find(c => c.filePath === `${path}/${entry.name}` && c.type === entry.type); + const commit = commits.find( + (c) => c.filePath === `${path}/${entry.name}` && c.type === entry.type, + ); if (commit) { resolve(commit); @@ -42,7 +44,7 @@ export function fetchLogsTree(client, path, offset, resolver = null) { .then(({ data: newData, headers }) => { const headerLogsOffset = headers['more-logs-offset']; const sourceData = client.readQuery({ query: commitsQuery }); - const data = produce(sourceData, draftState => { + const data = produce(sourceData, (draftState) => { draftState.commits.push(...normalizeData(newData, path)); }); client.writeQuery({ @@ -50,7 +52,7 @@ export function fetchLogsTree(client, path, offset, resolver = null) { data, }); - resolvers[path].forEach(r => resolveCommit(data.commits, path, r)); + resolvers[path].forEach((r) => resolveCommit(data.commits, path, r)); delete fetchpromises[path]; diff --git a/app/assets/javascripts/repository/utils/dom.js b/app/assets/javascripts/repository/utils/dom.js index abf726194ac..b667cd53b18 100644 --- a/app/assets/javascripts/repository/utils/dom.js +++ b/app/assets/javascripts/repository/utils/dom.js @@ -1,7 +1,9 @@ import { joinPaths } from '~/lib/utils/url_utility'; export const updateElementsVisibility = (selector, isVisible) => { - document.querySelectorAll(selector).forEach(elem => elem.classList.toggle('hidden', !isVisible)); + document + .querySelectorAll(selector) + .forEach((elem) => elem.classList.toggle('hidden', !isVisible)); }; export const updateFormAction = (selector, basePath, path) => { diff --git a/app/assets/javascripts/sidebar/components/labels/sidebar_labels.vue b/app/assets/javascripts/sidebar/components/labels/sidebar_labels.vue index 07abfa8d103..e01e1f032e3 100644 --- a/app/assets/javascripts/sidebar/components/labels/sidebar_labels.vue +++ b/app/assets/javascripts/sidebar/components/labels/sidebar_labels.vue @@ -50,9 +50,13 @@ export default { $(this.$el).trigger('hidden.gl.dropdown'); }, getUpdateVariables(dropdownLabels) { - const currentLabelIds = this.selectedLabels.map(label => label.id); - const userAddedLabelIds = dropdownLabels.filter(label => label.set).map(label => label.id); - const userRemovedLabelIds = dropdownLabels.filter(label => !label.set).map(label => label.id); + const currentLabelIds = this.selectedLabels.map((label) => label.id); + const userAddedLabelIds = dropdownLabels + .filter((label) => label.set) + .map((label) => label.id); + const userRemovedLabelIds = dropdownLabels + .filter((label) => !label.set) + .map((label) => label.id); const labelIds = difference(union(currentLabelIds, userAddedLabelIds), userRemovedLabelIds); @@ -116,7 +120,7 @@ export default { } const issuableType = camelCase(this.issuableType); - this.selectedLabels = data[mutationName]?.[issuableType]?.labels?.nodes?.map(label => ({ + this.selectedLabels = data[mutationName]?.[issuableType]?.labels?.nodes?.map((label) => ({ ...label, id: getIdFromGraphQLId(label.id), })); diff --git a/app/assets/javascripts/user_lists/store/utils.js b/app/assets/javascripts/user_lists/store/utils.js index f4e46947759..16f510bc32d 100644 --- a/app/assets/javascripts/user_lists/store/utils.js +++ b/app/assets/javascripts/user_lists/store/utils.js @@ -1,5 +1,6 @@ -export const parseUserIds = userIds => userIds.split(/\s*,\s*/g); +export const parseUserIds = (userIds) => userIds.split(/\s*,\s*/g); -export const stringifyUserIds = userIds => userIds.join(','); +export const stringifyUserIds = (userIds) => userIds.join(','); -export const getErrorMessages = error => [].concat(error?.response?.data?.message ?? error.message); +export const getErrorMessages = (error) => + [].concat(error?.response?.data?.message ?? error.message); 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 3e2b4cd35ab..655b867574d 100644 --- a/app/assets/javascripts/vue_shared/components/alert_details_table.vue +++ b/app/assets/javascripts/vue_shared/components/alert_details_table.vue @@ -49,7 +49,8 @@ export default { label: s__('AlertManagement|Key'), thClass, tdClass, - formatter: string => capitalizeFirstCharacter(convertToSentenceCase(splitCamelCase(string))), + formatter: (string) => + capitalizeFirstCharacter(convertToSentenceCase(splitCamelCase(string))), }, { key: 'value', diff --git a/app/assets/javascripts/vue_shared/components/registry/title_area.vue b/app/assets/javascripts/vue_shared/components/registry/title_area.vue index 4d82a954ced..bb9fe472138 100644 --- a/app/assets/javascripts/vue_shared/components/registry/title_area.vue +++ b/app/assets/javascripts/vue_shared/components/registry/title_area.vue @@ -1,5 +1,5 @@ <script> -import { GlAvatar, GlSprintf, GlLink } from '@gitlab/ui'; +import { GlAvatar, GlSprintf, GlLink, GlSkeletonLoader } from '@gitlab/ui'; export default { name: 'TitleArea', @@ -7,6 +7,7 @@ export default { GlAvatar, GlSprintf, GlLink, + GlSkeletonLoader, }, props: { avatar: { @@ -24,6 +25,11 @@ export default { default: () => [], required: false, }, + metadataLoading: { + type: Boolean, + required: false, + default: false, + }, }, data() { return { @@ -68,13 +74,23 @@ export default { </div> <div class="gl-display-flex gl-flex-wrap gl-align-items-center gl-mt-3"> - <div - v-for="(row, metadataIndex) in metadataSlots" - :key="metadataIndex" - class="gl-display-flex gl-align-items-center gl-mr-5" - > - <slot :name="row"></slot> - </div> + <template v-if="!metadataLoading"> + <div + v-for="(row, metadataIndex) in metadataSlots" + :key="metadataIndex" + class="gl-display-flex gl-align-items-center gl-mr-5" + > + <slot :name="row"></slot> + </div> + </template> + <template v-else> + <div class="gl-w-full"> + <gl-skeleton-loader :width="200" :height="16" preserve-aspect-ratio="xMinYMax meet"> + <circle cx="6" cy="8" r="6" /> + <rect x="16" y="4" width="200" height="8" rx="4" /> + </gl-skeleton-loader> + </div> + </template> </div> </div> <div v-if="$slots['right-actions']" class="gl-mt-3"> 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 b645758d891..01ba2cf5c39 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 @@ -62,7 +62,9 @@ export default { return files.every(this.isFileValid); }, isValidDragDataType({ dataTransfer }) { - return Boolean(dataTransfer && dataTransfer.types.some(t => t === VALID_DATA_TRANSFER_TYPE)); + return Boolean( + dataTransfer && dataTransfer.types.some((t) => t === VALID_DATA_TRANSFER_TYPE), + ); }, ondrop({ dataTransfer = {} }) { this.dragCounter = 0; diff --git a/app/assets/javascripts/vue_shared/constants.js b/app/assets/javascripts/vue_shared/constants.js index 5511145fba2..5262a15136b 100644 --- a/app/assets/javascripts/vue_shared/constants.js +++ b/app/assets/javascripts/vue_shared/constants.js @@ -54,5 +54,6 @@ export const timeRanges = [ }, ]; -export const defaultTimeRange = timeRanges.find(tr => tr.default); -export const getTimeWindow = timeWindowName => timeRanges.find(tr => tr.name === timeWindowName); +export const defaultTimeRange = timeRanges.find((tr) => tr.default); +export const getTimeWindow = (timeWindowName) => + timeRanges.find((tr) => tr.name === timeWindowName); diff --git a/app/graphql/mutations/releases/update.rb b/app/graphql/mutations/releases/update.rb index bf72b907679..33bfae80542 100644 --- a/app/graphql/mutations/releases/update.rb +++ b/app/graphql/mutations/releases/update.rb @@ -51,17 +51,17 @@ module Mutations params = scalars.with_indifferent_access - release_result = ::Releases::UpdateService.new(project, current_user, params).execute + result = ::Releases::UpdateService.new(project, current_user, params).execute - if release_result[:status] == :success + if result[:status] == :success { - release: release_result[:release], + release: result[:release], errors: [] } else { release: nil, - errors: [release_result[:message]] + errors: [result[:message]] } end end diff --git a/app/graphql/resolvers/projects/jira_projects_resolver.rb b/app/graphql/resolvers/projects/jira_projects_resolver.rb index 31f42d305b0..dcd662b4d6d 100644 --- a/app/graphql/resolvers/projects/jira_projects_resolver.rb +++ b/app/graphql/resolvers/projects/jira_projects_resolver.rb @@ -6,6 +6,7 @@ module Resolvers include Gitlab::Graphql::Authorize::AuthorizeResource type Types::Projects::Services::JiraProjectType.connection_type, null: true + authorize :admin_project argument :name, GraphQL::STRING_TYPE, @@ -31,10 +32,6 @@ module Resolvers end end - def authorized_resource?(project) - Ability.allowed?(context[:current_user], :admin_project, project) - end - private alias_method :jira_service, :object diff --git a/app/graphql/resolvers/release_milestones_resolver.rb b/app/graphql/resolvers/release_milestones_resolver.rb new file mode 100644 index 00000000000..7582c91272f --- /dev/null +++ b/app/graphql/resolvers/release_milestones_resolver.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module Resolvers + class ReleaseMilestonesResolver < BaseResolver + type Types::MilestoneType.connection_type, null: true + + alias_method :release, :object + + def resolve(**args) + offset_pagination(release.milestones.order_by_dates_and_title) + end + end +end diff --git a/app/graphql/types/release_type.rb b/app/graphql/types/release_type.rb index b715b981483..e7afa7ce7f7 100644 --- a/app/graphql/types/release_type.rb +++ b/app/graphql/types/release_type.rb @@ -35,7 +35,8 @@ module Types field :links, Types::ReleaseLinksType, null: true, method: :itself, description: 'Links of the release' field :milestones, Types::MilestoneType.connection_type, null: true, - description: 'Milestones associated to the release' + description: 'Milestones associated to the release', + resolver: ::Resolvers::ReleaseMilestonesResolver field :evidences, Types::EvidenceType.connection_type, null: true, description: 'Evidence for the release' diff --git a/app/models/milestone.rb b/app/models/milestone.rb index c244150e7a3..aa4ddfede99 100644 --- a/app/models/milestone.rb +++ b/app/models/milestone.rb @@ -33,6 +33,7 @@ class Milestone < ApplicationRecord scope :order_by_name_asc, -> { order(Arel::Nodes::Ascending.new(arel_table[:title].lower)) } scope :reorder_by_due_date_asc, -> { reorder(Gitlab::Database.nulls_last_order('due_date', 'ASC')) } scope :with_api_entity_associations, -> { preload(project: [:project_feature, :route, namespace: :route]) } + scope :order_by_dates_and_title, -> { order(due_date: :asc, start_date: :asc, title: :asc) } validates_associated :milestone_releases, message: -> (_, obj) { obj[:value].map(&:errors).map(&:full_messages).join(",") } diff --git a/app/models/release.rb b/app/models/release.rb index bebf91fb247..2b82fdc37f6 100644 --- a/app/models/release.rb +++ b/app/models/release.rb @@ -82,7 +82,7 @@ class Release < ApplicationRecord end def milestone_titles - self.milestones.map {|m| m.title }.sort.join(", ") + self.milestones.order_by_dates_and_title.map {|m| m.title }.join(', ') end def to_hook_data(action) |