diff options
author | Stan Hu <stanhu@gmail.com> | 2018-07-25 05:12:24 -0700 |
---|---|---|
committer | Stan Hu <stanhu@gmail.com> | 2018-07-25 05:12:24 -0700 |
commit | 537f87a169576544b26347b5b3a6ab22d2cbfc00 (patch) | |
tree | 58cb66cf9639ef46acc4927fef0b4e0a84269568 /app | |
parent | f94b52256d1bedfe6b01ef31f0bed0615b10d918 (diff) | |
parent | d22db4f492d5ae676bea6bc699203d2fc120fe96 (diff) | |
download | gitlab-ce-537f87a169576544b26347b5b3a6ab22d2cbfc00.tar.gz |
Merge branch 'master' into sh-support-bitbucket-server-import
Diffstat (limited to 'app')
278 files changed, 1434 insertions, 716 deletions
diff --git a/app/assets/javascripts/diffs/components/diff_line_gutter_content.vue b/app/assets/javascripts/diffs/components/diff_line_gutter_content.vue index 0fe0007057b..d184a76f038 100644 --- a/app/assets/javascripts/diffs/components/diff_line_gutter_content.vue +++ b/app/assets/javascripts/diffs/components/diff_line_gutter_content.vue @@ -71,6 +71,11 @@ export default { required: false, default: false, }, + discussions: { + type: Array, + required: false, + default: () => [], + }, }, computed: { ...mapState({ @@ -78,7 +83,6 @@ export default { diffFiles: state => state.diffs.diffFiles, }), ...mapGetters(['isLoggedIn']), - ...mapGetters('diffs', ['discussionsByLineCode']), lineHref() { return this.lineCode ? `#${this.lineCode}` : '#'; }, @@ -88,24 +92,19 @@ export default { this.showCommentButton && !this.isMatchLine && !this.isContextLine && - !this.hasDiscussions && - !this.isMetaLine + !this.isMetaLine && + !this.hasDiscussions ); }, - discussions() { - return this.discussionsByLineCode[this.lineCode] || []; - }, hasDiscussions() { return this.discussions.length > 0; }, shouldShowAvatarsOnGutter() { - let render = this.hasDiscussions && this.showCommentButton; - if (!this.lineType && this.linePosition === LINE_POSITION_RIGHT) { - render = false; + return false; } - return render; + return this.hasDiscussions && this.showCommentButton; }, }, methods: { diff --git a/app/assets/javascripts/diffs/components/diff_table_cell.vue b/app/assets/javascripts/diffs/components/diff_table_cell.vue index 5962f30d9bb..e8e8ddc6c5e 100644 --- a/app/assets/javascripts/diffs/components/diff_table_cell.vue +++ b/app/assets/javascripts/diffs/components/diff_table_cell.vue @@ -67,6 +67,11 @@ export default { required: false, default: false, }, + discussions: { + type: Array, + required: false, + default: () => [], + }, }, computed: { ...mapGetters(['isLoggedIn']), @@ -136,6 +141,7 @@ export default { :is-match-line="isMatchLine" :is-context-line="isContentLine" :is-meta-line="isMetaLine" + :discussions="discussions" /> </td> </template> diff --git a/app/assets/javascripts/diffs/components/inline_diff_comment_row.vue b/app/assets/javascripts/diffs/components/inline_diff_comment_row.vue index a6f011ff31e..1b5ae5e9f75 100644 --- a/app/assets/javascripts/diffs/components/inline_diff_comment_row.vue +++ b/app/assets/javascripts/diffs/components/inline_diff_comment_row.vue @@ -1,5 +1,5 @@ <script> -import { mapState, mapGetters } from 'vuex'; +import { mapState } from 'vuex'; import diffDiscussions from './diff_discussions.vue'; import diffLineNoteForm from './diff_line_note_form.vue'; @@ -21,15 +21,16 @@ export default { type: Number, required: true, }, + discussions: { + type: Array, + required: false, + default: () => [], + }, }, computed: { ...mapState({ diffLineCommentForms: state => state.diffs.diffLineCommentForms, }), - ...mapGetters('diffs', ['discussionsByLineCode']), - discussions() { - return this.discussionsByLineCode[this.line.lineCode] || []; - }, className() { return this.discussions.length ? '' : 'js-temp-notes-holder'; }, diff --git a/app/assets/javascripts/diffs/components/inline_diff_table_row.vue b/app/assets/javascripts/diffs/components/inline_diff_table_row.vue index 0e306f39a9f..32d65ff994f 100644 --- a/app/assets/javascripts/diffs/components/inline_diff_table_row.vue +++ b/app/assets/javascripts/diffs/components/inline_diff_table_row.vue @@ -33,6 +33,11 @@ export default { required: false, default: false, }, + discussions: { + type: Array, + required: false, + default: () => [], + }, }, data() { return { @@ -89,6 +94,7 @@ export default { :is-bottom="isBottom" :is-hover="isHover" :show-comment-button="true" + :discussions="discussions" class="diff-line-num old_line" /> <diff-table-cell @@ -98,6 +104,7 @@ export default { :line-type="newLineType" :is-bottom="isBottom" :is-hover="isHover" + :discussions="discussions" class="diff-line-num new_line" /> <td diff --git a/app/assets/javascripts/diffs/components/inline_diff_view.vue b/app/assets/javascripts/diffs/components/inline_diff_view.vue index 8e491d293e5..5f30cc57a59 100644 --- a/app/assets/javascripts/diffs/components/inline_diff_view.vue +++ b/app/assets/javascripts/diffs/components/inline_diff_view.vue @@ -20,7 +20,11 @@ export default { }, }, computed: { - ...mapGetters('diffs', ['commitId', 'discussionsByLineCode']), + ...mapGetters('diffs', [ + 'commitId', + 'shouldRenderInlineCommentRow', + 'singleDiscussionByLineCode', + ]), ...mapState({ diffLineCommentForms: state => state.diffs.diffLineCommentForms, }), @@ -34,18 +38,7 @@ export default { return window.gon.user_color_scheme; }, }, - methods: { - shouldRenderCommentRow(line) { - if (this.diffLineCommentForms[line.lineCode]) return true; - - const lineDiscussions = this.discussionsByLineCode[line.lineCode]; - if (lineDiscussions === undefined) { - return false; - } - - return lineDiscussions.every(discussion => discussion.expanded); - }, - }, + methods: {}, }; </script> @@ -64,13 +57,15 @@ export default { :line="line" :is-bottom="index + 1 === diffLinesLength" :key="line.lineCode" + :discussions="singleDiscussionByLineCode(line.lineCode)" /> <inline-diff-comment-row - v-if="shouldRenderCommentRow(line)" + v-if="shouldRenderInlineCommentRow(line)" :diff-file-hash="diffFile.fileHash" :line="line" :line-index="index" :key="index" + :discussions="singleDiscussionByLineCode(line.lineCode)" /> </template> </tbody> diff --git a/app/assets/javascripts/diffs/components/parallel_diff_comment_row.vue b/app/assets/javascripts/diffs/components/parallel_diff_comment_row.vue index 05e5cafc717..bb9a65c83fa 100644 --- a/app/assets/javascripts/diffs/components/parallel_diff_comment_row.vue +++ b/app/assets/javascripts/diffs/components/parallel_diff_comment_row.vue @@ -1,5 +1,5 @@ <script> -import { mapState, mapGetters } from 'vuex'; +import { mapState } from 'vuex'; import diffDiscussions from './diff_discussions.vue'; import diffLineNoteForm from './diff_line_note_form.vue'; @@ -21,48 +21,51 @@ export default { type: Number, required: true, }, + leftDiscussions: { + type: Array, + required: false, + default: () => [], + }, + rightDiscussions: { + type: Array, + required: false, + default: () => [], + }, }, computed: { ...mapState({ diffLineCommentForms: state => state.diffs.diffLineCommentForms, }), - ...mapGetters('diffs', ['discussionsByLineCode']), leftLineCode() { return this.line.left.lineCode; }, rightLineCode() { return this.line.right.lineCode; }, - hasDiscussion() { - const discussions = this.discussionsByLineCode; - - return discussions[this.leftLineCode] || discussions[this.rightLineCode]; - }, hasExpandedDiscussionOnLeft() { - const discussions = this.discussionsByLineCode[this.leftLineCode]; - + const discussions = this.leftDiscussions; return discussions ? discussions.every(discussion => discussion.expanded) : false; }, hasExpandedDiscussionOnRight() { - const discussions = this.discussionsByLineCode[this.rightLineCode]; - + const discussions = this.rightDiscussions; return discussions ? discussions.every(discussion => discussion.expanded) : false; }, hasAnyExpandedDiscussion() { return this.hasExpandedDiscussionOnLeft || this.hasExpandedDiscussionOnRight; }, shouldRenderDiscussionsOnLeft() { - return this.discussionsByLineCode[this.leftLineCode] && this.hasExpandedDiscussionOnLeft; + return this.leftDiscussions && this.hasExpandedDiscussionOnLeft; }, shouldRenderDiscussionsOnRight() { - return ( - this.discussionsByLineCode[this.rightLineCode] && - this.hasExpandedDiscussionOnRight && - this.line.right.type - ); + return this.rightDiscussions && this.hasExpandedDiscussionOnRight && this.line.right.type; + }, + showRightSideCommentForm() { + return this.line.right.type && this.diffLineCommentForms[this.rightLineCode]; }, className() { - return this.hasDiscussion ? '' : 'js-temp-notes-holder'; + return this.leftDiscussions.length > 0 || this.rightDiscussions.length > 0 + ? '' + : 'js-temp-notes-holder'; }, }, }; @@ -80,13 +83,12 @@ export default { class="content" > <diff-discussions - v-if="discussionsByLineCode[leftLineCode].length" - :discussions="discussionsByLineCode[leftLineCode]" + v-if="leftDiscussions.length" + :discussions="leftDiscussions" /> </div> <diff-line-note-form - v-if="diffLineCommentForms[leftLineCode] && - diffLineCommentForms[leftLineCode]" + v-if="diffLineCommentForms[leftLineCode]" :diff-file-hash="diffFileHash" :line="line.left" :note-target-line="line.left" @@ -100,13 +102,12 @@ export default { class="content" > <diff-discussions - v-if="discussionsByLineCode[rightLineCode].length" - :discussions="discussionsByLineCode[rightLineCode]" + v-if="rightDiscussions.length" + :discussions="rightDiscussions" /> </div> <diff-line-note-form - v-if="diffLineCommentForms[rightLineCode] && - diffLineCommentForms[rightLineCode] && line.right.type" + v-if="showRightSideCommentForm" :diff-file-hash="diffFileHash" :line="line.right" :note-target-line="line.right" diff --git a/app/assets/javascripts/diffs/components/parallel_diff_table_row.vue b/app/assets/javascripts/diffs/components/parallel_diff_table_row.vue index 0031cedc68f..d4e54c2bd00 100644 --- a/app/assets/javascripts/diffs/components/parallel_diff_table_row.vue +++ b/app/assets/javascripts/diffs/components/parallel_diff_table_row.vue @@ -36,6 +36,16 @@ export default { required: false, default: false, }, + leftDiscussions: { + type: Array, + required: false, + default: () => [], + }, + rightDiscussions: { + type: Array, + required: false, + default: () => [], + }, }, data() { return { @@ -116,6 +126,7 @@ export default { :is-hover="isLeftHover" :show-comment-button="true" :diff-view-type="parallelDiffViewType" + :discussions="leftDiscussions" class="diff-line-num old_line" /> <td @@ -136,6 +147,7 @@ export default { :is-hover="isRightHover" :show-comment-button="true" :diff-view-type="parallelDiffViewType" + :discussions="rightDiscussions" class="diff-line-num new_line" /> <td diff --git a/app/assets/javascripts/diffs/components/parallel_diff_view.vue b/app/assets/javascripts/diffs/components/parallel_diff_view.vue index 8f8d6bbc818..4d97cb6d15d 100644 --- a/app/assets/javascripts/diffs/components/parallel_diff_view.vue +++ b/app/assets/javascripts/diffs/components/parallel_diff_view.vue @@ -21,7 +21,11 @@ export default { }, }, computed: { - ...mapGetters('diffs', ['commitId', 'discussionsByLineCode']), + ...mapGetters('diffs', [ + 'commitId', + 'singleDiscussionByLineCode', + 'shouldRenderParallelCommentRow', + ]), ...mapState({ diffLineCommentForms: state => state.diffs.diffLineCommentForms, }), @@ -51,32 +55,6 @@ export default { return window.gon.user_color_scheme; }, }, - methods: { - shouldRenderCommentRow(line) { - const leftLineCode = line.left.lineCode; - const rightLineCode = line.right.lineCode; - const discussions = this.discussionsByLineCode; - const leftDiscussions = discussions[leftLineCode]; - const rightDiscussions = discussions[rightLineCode]; - const hasDiscussion = leftDiscussions || rightDiscussions; - - const hasExpandedDiscussionOnLeft = leftDiscussions - ? leftDiscussions.every(discussion => discussion.expanded) - : false; - const hasExpandedDiscussionOnRight = rightDiscussions - ? rightDiscussions.every(discussion => discussion.expanded) - : false; - - if (hasDiscussion && (hasExpandedDiscussionOnLeft || hasExpandedDiscussionOnRight)) { - return true; - } - - const hasCommentFormOnLeft = this.diffLineCommentForms[leftLineCode]; - const hasCommentFormOnRight = this.diffLineCommentForms[rightLineCode]; - - return hasCommentFormOnLeft || hasCommentFormOnRight; - }, - }, }; </script> @@ -97,13 +75,17 @@ export default { :line="line" :is-bottom="index + 1 === diffLinesLength" :key="index" + :left-discussions="singleDiscussionByLineCode(line.left.lineCode)" + :right-discussions="singleDiscussionByLineCode(line.right.lineCode)" /> <parallel-diff-comment-row - v-if="shouldRenderCommentRow(line)" + v-if="shouldRenderParallelCommentRow(line)" :key="`dcr-${index}`" :line="line" :diff-file-hash="diffFile.fileHash" :line-index="index" + :left-discussions="singleDiscussionByLineCode(line.left.lineCode)" + :right-discussions="singleDiscussionByLineCode(line.right.lineCode)" /> </template> </tbody> diff --git a/app/assets/javascripts/diffs/store/getters.js b/app/assets/javascripts/diffs/store/getters.js index d3881fa1a0a..c7b9b1a16e6 100644 --- a/app/assets/javascripts/diffs/store/getters.js +++ b/app/assets/javascripts/diffs/store/getters.js @@ -75,19 +75,21 @@ export const discussionsByLineCode = (state, getters, rootState, rootGetters) => const isDiffDiscussion = note.diff_discussion; const hasLineCode = note.line_code; const isResolvable = note.resolvable; - const diffRefs = diffRefsByLineCode[note.line_code]; - if (isDiffDiscussion && hasLineCode && isResolvable && diffRefs) { - const refs = convertObjectPropsToCamelCase(note.position.formatter); - const originalRefs = convertObjectPropsToCamelCase(note.original_position.formatter); + if (isDiffDiscussion && hasLineCode && isResolvable) { + const diffRefs = diffRefsByLineCode[note.line_code]; + if (diffRefs) { + const refs = convertObjectPropsToCamelCase(note.position.formatter); + const originalRefs = convertObjectPropsToCamelCase(note.original_position.formatter); - if (_.isEqual(refs, diffRefs) || _.isEqual(originalRefs, diffRefs)) { - const lineCode = note.line_code; + if (_.isEqual(refs, diffRefs) || _.isEqual(originalRefs, diffRefs)) { + const lineCode = note.line_code; - if (acc[lineCode]) { - acc[lineCode].push(note); - } else { - acc[lineCode] = [note]; + if (acc[lineCode]) { + acc[lineCode].push(note); + } else { + acc[lineCode] = [note]; + } } } } @@ -96,6 +98,47 @@ export const discussionsByLineCode = (state, getters, rootState, rootGetters) => }, {}); }; +export const singleDiscussionByLineCode = (state, getters) => lineCode => { + if (!lineCode) return []; + const discussions = getters.discussionsByLineCode; + return discussions[lineCode] || []; +}; + +export const shouldRenderParallelCommentRow = (state, getters) => line => { + const leftLineCode = line.left.lineCode; + const rightLineCode = line.right.lineCode; + const leftDiscussions = getters.singleDiscussionByLineCode(leftLineCode); + const rightDiscussions = getters.singleDiscussionByLineCode(rightLineCode); + const hasDiscussion = leftDiscussions.length || rightDiscussions.length; + + const hasExpandedDiscussionOnLeft = leftDiscussions.length + ? leftDiscussions.every(discussion => discussion.expanded) + : false; + const hasExpandedDiscussionOnRight = rightDiscussions.length + ? rightDiscussions.every(discussion => discussion.expanded) + : false; + + if (hasDiscussion && (hasExpandedDiscussionOnLeft || hasExpandedDiscussionOnRight)) { + return true; + } + + const hasCommentFormOnLeft = state.diffLineCommentForms[leftLineCode]; + const hasCommentFormOnRight = state.diffLineCommentForms[rightLineCode]; + + return hasCommentFormOnLeft || hasCommentFormOnRight; +}; + +export const shouldRenderInlineCommentRow = (state, getters) => line => { + if (state.diffLineCommentForms[line.lineCode]) return true; + + const lineDiscussions = getters.singleDiscussionByLineCode(line.lineCode); + if (lineDiscussions.length === 0) { + return false; + } + + return lineDiscussions.every(discussion => discussion.expanded); +}; + // prevent babel-plugin-rewire from generating an invalid default during karma∂ tests export const getDiffFileByHash = state => fileHash => state.diffFiles.find(file => file.fileHash === fileHash); diff --git a/app/assets/javascripts/gpg_badges.js b/app/assets/javascripts/gpg_badges.js index 029fd6a67d4..efba6fc1aff 100644 --- a/app/assets/javascripts/gpg_badges.js +++ b/app/assets/javascripts/gpg_badges.js @@ -1,23 +1,36 @@ import $ from 'jquery'; import { parseQueryStringIntoObject } from '~/lib/utils/common_utils'; import axios from '~/lib/utils/axios_utils'; -import flash from '~/flash'; +import createFlash from '~/flash'; import { __ } from '~/locale'; export default class GpgBadges { static fetch() { - const badges = $('.js-loading-gpg-badge'); const tag = $('.js-signature-container'); + if (tag.length === 0) { + return Promise.resolve(); + } + + const badges = $('.js-loading-gpg-badge'); badges.html('<i class="fa fa-spinner fa-spin"></i>'); + const displayError = () => createFlash(__('An error occurred while loading commit signatures')); + + const endpoint = tag.data('signaturesPath'); + if (!endpoint) { + displayError(); + return Promise.reject(new Error('Missing commit signatures endpoint!')); + } + const params = parseQueryStringIntoObject(tag.serialize()); - return axios.get(tag.data('signaturesPath'), { params }) - .then(({ data }) => { - data.signatures.forEach((signature) => { - badges.filter(`[data-commit-sha="${signature.commit_sha}"]`).replaceWith(signature.html); - }); - }) - .catch(() => flash(__('An error occurred while loading commits'))); + return axios + .get(endpoint, { params }) + .then(({ data }) => { + data.signatures.forEach(signature => { + badges.filter(`[data-commit-sha="${signature.commit_sha}"]`).replaceWith(signature.html); + }); + }) + .catch(displayError); } } diff --git a/app/assets/javascripts/issue_show/components/edited.vue b/app/assets/javascripts/issue_show/components/edited.vue index 5ff5b1630b1..05cd976f196 100644 --- a/app/assets/javascripts/issue_show/components/edited.vue +++ b/app/assets/javascripts/issue_show/components/edited.vue @@ -46,7 +46,7 @@ by <a :href="updatedByPath" - class="author_link" + class="author-link" > <span>{{ updatedByName }}</span> </a> diff --git a/app/assets/javascripts/lib/utils/common_utils.js b/app/assets/javascripts/lib/utils/common_utils.js index 6b7550efff8..2f3dd6f6cbc 100644 --- a/app/assets/javascripts/lib/utils/common_utils.js +++ b/app/assets/javascripts/lib/utils/common_utils.js @@ -541,6 +541,26 @@ export const addSelectOnFocusBehaviour = (selector = '.js-select-on-focus') => { }); }; +/** + * Method to round of values with decimal places + * with provided precision. + * + * Taken from https://stackoverflow.com/a/7343013/414749 + * + * Eg; roundOffFloat(3.141592, 3) = 3.142 + * + * Refer to spec/javascripts/lib/utils/common_utils_spec.js for + * more supported examples. + * + * @param {Float} number + * @param {Number} precision + */ +export const roundOffFloat = (number, precision = 0) => { + // eslint-disable-next-line no-restricted-properties + const multiplier = Math.pow(10, precision); + return Math.round(number * multiplier) / multiplier; +}; + window.gl = window.gl || {}; window.gl.utils = { ...(window.gl.utils || {}), diff --git a/app/assets/javascripts/lib/utils/poll.js b/app/assets/javascripts/lib/utils/poll.js index 7fca80c2fdb..91d8c30744f 100644 --- a/app/assets/javascripts/lib/utils/poll.js +++ b/app/assets/javascripts/lib/utils/poll.js @@ -38,7 +38,7 @@ import { normalizeHeaders } from './common_utils'; * } else { * poll.stop(); * } -* }); + * }); * * 1. Checks for response and headers before start polling * 2. Interval is provided by `Poll-Interval` header. @@ -51,8 +51,8 @@ export default class Poll { constructor(options = {}) { this.options = options; this.options.data = options.data || {}; - this.options.notificationCallback = options.notificationCallback || - function notificationCallback() {}; + this.options.notificationCallback = + options.notificationCallback || function notificationCallback() {}; this.intervalHeader = 'POLL-INTERVAL'; this.timeoutID = null; @@ -63,6 +63,7 @@ export default class Poll { const headers = normalizeHeaders(response.headers); const pollInterval = parseInt(headers[this.intervalHeader], 10); if (pollInterval > 0 && response.status === httpStatusCodes.OK && this.canPoll) { + clearTimeout(this.timeoutID); this.timeoutID = setTimeout(() => { this.makeRequest(); }, pollInterval); @@ -77,11 +78,11 @@ export default class Poll { notificationCallback(true); return resource[method](data) - .then((response) => { + .then(response => { this.checkConditions(response); notificationCallback(false); }) - .catch((error) => { + .catch(error => { notificationCallback(false); if (error.status === httpStatusCodes.ABORTED) { return; diff --git a/app/assets/javascripts/notes/components/note_edited_text.vue b/app/assets/javascripts/notes/components/note_edited_text.vue index 391bb2ae179..d848335022f 100644 --- a/app/assets/javascripts/notes/components/note_edited_text.vue +++ b/app/assets/javascripts/notes/components/note_edited_text.vue @@ -42,7 +42,7 @@ export default { by <a :href="editedBy.path" - class="js-vue-author author_link"> + class="js-vue-author author-link"> {{ editedBy.name }} </a> </template> diff --git a/app/assets/javascripts/notes/index.js b/app/assets/javascripts/notes/index.js index 6dd4c9d66ac..3aef30c608c 100644 --- a/app/assets/javascripts/notes/index.js +++ b/app/assets/javascripts/notes/index.js @@ -15,7 +15,7 @@ document.addEventListener('DOMContentLoaded', () => { const notesDataset = document.getElementById('js-vue-notes').dataset; const parsedUserData = JSON.parse(notesDataset.currentUserData); const noteableData = JSON.parse(notesDataset.noteableData); - const { markdownVersion } = notesDataset; + const markdownVersion = parseInt(notesDataset.markdownVersion, 10); let currentUserData = {}; noteableData.noteableType = notesDataset.noteableType; diff --git a/app/assets/javascripts/notes/stores/mutations.js b/app/assets/javascripts/notes/stores/mutations.js index ab6a95e2601..e1b159142c9 100644 --- a/app/assets/javascripts/notes/stores/mutations.js +++ b/app/assets/javascripts/notes/stores/mutations.js @@ -174,27 +174,19 @@ export default { [types.UPDATE_NOTE](state, note) { const noteObj = utils.findNoteObjectById(state.discussions, note.discussion_id); - if (noteObj.individual_note) { noteObj.notes.splice(0, 1, note); } else { const comment = utils.findNoteObjectById(noteObj.notes, note.id); - noteObj.notes.splice(noteObj.notes.indexOf(comment), 1, note); + Object.assign(comment, note); } }, [types.UPDATE_DISCUSSION](state, noteData) { const note = noteData; - let index = 0; - - state.discussions.forEach((n, i) => { - if (n.id === note.id) { - index = i; - } - }); - + const selectedDiscussion = state.discussions.find(n => n.id === note.id); note.expanded = true; // override expand flag to prevent collapse - state.discussions.splice(index, 1, note); + Object.assign(selectedDiscussion, note); }, [types.CLOSE_ISSUE](state) { @@ -215,12 +207,9 @@ export default { [types.SET_DISCUSSION_DIFF_LINES](state, { discussionId, diffLines }) { const discussion = utils.findNoteObjectById(state.discussions, discussionId); - const index = state.discussions.indexOf(discussion); - const discussionWithDiffLines = Object.assign({}, discussion, { + Object.assign(discussion, { truncated_diff_lines: diffLines, }); - - state.discussions.splice(index, 1, discussionWithDiffLines); }, }; diff --git a/app/assets/javascripts/notes/stores/utils.js b/app/assets/javascripts/notes/stores/utils.js index a0e096ebfaf..c4a812c5af4 100644 --- a/app/assets/javascripts/notes/stores/utils.js +++ b/app/assets/javascripts/notes/stores/utils.js @@ -2,13 +2,11 @@ import AjaxCache from '~/lib/utils/ajax_cache'; const REGEX_QUICK_ACTIONS = /^\/\w+.*$/gm; -export const findNoteObjectById = (notes, id) => - notes.filter(n => n.id === id)[0]; +export const findNoteObjectById = (notes, id) => notes.find(n => n.id === id); export const getQuickActionText = note => { let text = 'Applying command'; - const quickActions = - AjaxCache.get(gl.GfmAutoComplete.dataSources.commands) || []; + const quickActions = AjaxCache.get(gl.GfmAutoComplete.dataSources.commands) || []; const executedCommands = quickActions.filter(command => { const commandRegex = new RegExp(`/${command.name}`); @@ -29,5 +27,4 @@ export const getQuickActionText = note => { export const hasQuickActions = note => REGEX_QUICK_ACTIONS.test(note); -export const stripQuickActions = note => - note.replace(REGEX_QUICK_ACTIONS, '').trim(); +export const stripQuickActions = note => note.replace(REGEX_QUICK_ACTIONS, '').trim(); diff --git a/app/assets/javascripts/pages/projects/blob/show/index.js b/app/assets/javascripts/pages/projects/blob/show/index.js index 85c6862d629..84e5bb3c46e 100644 --- a/app/assets/javascripts/pages/projects/blob/show/index.js +++ b/app/assets/javascripts/pages/projects/blob/show/index.js @@ -2,6 +2,7 @@ import Vue from 'vue'; import commitPipelineStatus from '~/projects/tree/components/commit_pipeline_status_component.vue'; import BlobViewer from '~/blob/viewer/index'; import initBlob from '~/pages/projects/init_blob'; +import GpgBadges from '~/gpg_badges'; document.addEventListener('DOMContentLoaded', () => { new BlobViewer(); // eslint-disable-line no-new @@ -26,4 +27,6 @@ document.addEventListener('DOMContentLoaded', () => { }, }); } + + GpgBadges.fetch(); }); diff --git a/app/assets/javascripts/pages/projects/show/index.js b/app/assets/javascripts/pages/projects/show/index.js index 3b0f0f960b8..d2dc0c4570e 100644 --- a/app/assets/javascripts/pages/projects/show/index.js +++ b/app/assets/javascripts/pages/projects/show/index.js @@ -7,6 +7,7 @@ import TreeView from '~/tree'; import BlobViewer from '~/blob/viewer/index'; import Activities from '~/activities'; import { ajaxGet } from '~/lib/utils/common_utils'; +import GpgBadges from '~/gpg_badges'; import Star from '../../../star'; import notificationsDropdown from '../../../notifications_dropdown'; @@ -38,4 +39,6 @@ document.addEventListener('DOMContentLoaded', () => { $(treeSlider).waitForImages(() => { ajaxGet(document.querySelector('.js-tree-content').dataset.logsPath); }); + + GpgBadges.fetch(); }); diff --git a/app/assets/javascripts/pages/projects/tree/show/index.js b/app/assets/javascripts/pages/projects/tree/show/index.js index 7ad082a5e61..33d69d891d8 100644 --- a/app/assets/javascripts/pages/projects/tree/show/index.js +++ b/app/assets/javascripts/pages/projects/tree/show/index.js @@ -2,6 +2,7 @@ import $ from 'jquery'; import Vue from 'vue'; import initBlob from '~/blob_edit/blob_bundle'; import commitPipelineStatus from '~/projects/tree/components/commit_pipeline_status_component.vue'; +import GpgBadges from '~/gpg_badges'; import TreeView from '../../../../tree'; import ShortcutsNavigation from '../../../../shortcuts_navigation'; import BlobViewer from '../../../../blob/viewer'; @@ -14,7 +15,8 @@ document.addEventListener('DOMContentLoaded', () => { new BlobViewer(); // eslint-disable-line no-new new NewCommitForm($('.js-create-dir-form')); // eslint-disable-line no-new $('#tree-slider').waitForImages(() => - ajaxGet(document.querySelector('.js-tree-content').dataset.logsPath)); + ajaxGet(document.querySelector('.js-tree-content').dataset.logsPath), + ); initBlob(); const commitPipelineStatusEl = document.querySelector('.js-commit-pipeline-status'); @@ -36,4 +38,6 @@ document.addEventListener('DOMContentLoaded', () => { }, }); } + + GpgBadges.fetch(); }); diff --git a/app/assets/javascripts/projects/tree/components/commit_pipeline_status_component.vue b/app/assets/javascripts/projects/tree/components/commit_pipeline_status_component.vue index a4c7c143e56..1c1e17563a1 100644 --- a/app/assets/javascripts/projects/tree/components/commit_pipeline_status_component.vue +++ b/app/assets/javascripts/projects/tree/components/commit_pipeline_status_component.vue @@ -1,27 +1,27 @@ <script> - import Visibility from 'visibilityjs'; - import ciIcon from '~/vue_shared/components/ci_icon.vue'; - import loadingIcon from '~/vue_shared/components/loading_icon.vue'; - import Poll from '~/lib/utils/poll'; - import Flash from '~/flash'; - import { s__, sprintf } from '~/locale'; - import tooltip from '~/vue_shared/directives/tooltip'; - import CommitPipelineService from '../services/commit_pipeline_service'; +import Visibility from 'visibilityjs'; +import ciIcon from '~/vue_shared/components/ci_icon.vue'; +import loadingIcon from '~/vue_shared/components/loading_icon.vue'; +import Poll from '~/lib/utils/poll'; +import Flash from '~/flash'; +import { s__, sprintf } from '~/locale'; +import tooltip from '~/vue_shared/directives/tooltip'; +import CommitPipelineService from '../services/commit_pipeline_service'; - export default { - directives: { - tooltip, +export default { + directives: { + tooltip, + }, + components: { + ciIcon, + loadingIcon, + }, + props: { + endpoint: { + type: String, + required: true, }, - components: { - ciIcon, - loadingIcon, - }, - props: { - endpoint: { - type: String, - required: true, - }, - /* This prop can be used to replace some of the `render_commit_status` + /* This prop can be used to replace some of the `render_commit_status` used across GitLab, this way we could use this vue component and add a realtime status where it makes sense realtime: { @@ -29,76 +29,77 @@ required: false, default: true, }, */ + }, + data() { + return { + ciStatus: {}, + isLoading: true, + }; + }, + computed: { + statusTitle() { + return sprintf(s__('Commits|Commit: %{commitText}'), { commitText: this.ciStatus.text }); }, - data() { - return { - ciStatus: {}, - isLoading: true, - }; - }, - computed: { - statusTitle() { - return sprintf(s__('Commits|Commit: %{commitText}'), { commitText: this.ciStatus.text }); - }, + }, + mounted() { + this.service = new CommitPipelineService(this.endpoint); + this.initPolling(); + }, + methods: { + successCallback(res) { + const { pipelines } = res.data; + if (pipelines.length > 0) { + // The pipeline entity always keeps the latest pipeline info on the `details.status` + this.ciStatus = pipelines[0].details.status; + } + this.isLoading = false; }, - mounted() { - this.service = new CommitPipelineService(this.endpoint); - this.initPolling(); + errorCallback() { + this.ciStatus = { + text: 'not found', + icon: 'status_notfound', + group: 'notfound', + }; + this.isLoading = false; + Flash(s__('Something went wrong on our end')); }, - methods: { - successCallback(res) { - const { pipelines } = res.data; - if (pipelines.length > 0) { - // The pipeline entity always keeps the latest pipeline info on the `details.status` - this.ciStatus = pipelines[0].details.status; - } - this.isLoading = false; - }, - errorCallback() { - this.ciStatus = { - text: 'not found', - icon: 'status_notfound', - group: 'notfound', - }; - this.isLoading = false; - Flash(s__('Something went wrong on our end')); - }, - initPolling() { - this.poll = new Poll({ - resource: this.service, - method: 'fetchData', - successCallback: response => this.successCallback(response), - errorCallback: this.errorCallback, - }); + initPolling() { + this.poll = new Poll({ + resource: this.service, + method: 'fetchData', + successCallback: response => this.successCallback(response), + errorCallback: this.errorCallback, + }); + + if (!Visibility.hidden()) { + this.isLoading = true; + this.poll.makeRequest(); + } else { + this.fetchPipelineCommitData(); + } + Visibility.change(() => { if (!Visibility.hidden()) { - this.isLoading = true; - this.poll.makeRequest(); + this.poll.restart(); } else { - this.fetchPipelineCommitData(); + this.poll.stop(); } - - Visibility.change(() => { - if (!Visibility.hidden()) { - this.poll.restart(); - } else { - this.poll.stop(); - } - }); - }, - fetchPipelineCommitData() { - this.service.fetchData() - .then(this.successCallback) - .catch(this.errorCallback); - }, + }); }, - destroy() { - this.poll.stop(); + fetchPipelineCommitData() { + this.service + .fetchData() + .then(this.successCallback) + .catch(this.errorCallback); }, - }; + }, + destroy() { + this.poll.stop(); + }, +}; </script> <template> - <div> + <div class="ci-status-link"> <loading-icon v-if="isLoading" label="Loading pipeline status" @@ -113,6 +114,7 @@ :title="statusTitle" :aria-label="statusTitle" :status="ciStatus" + :size="24" data-container="body" /> </a> diff --git a/app/assets/javascripts/reports/store/actions.js b/app/assets/javascripts/reports/store/actions.js new file mode 100644 index 00000000000..15c077b0fd8 --- /dev/null +++ b/app/assets/javascripts/reports/store/actions.js @@ -0,0 +1,67 @@ +import Visibility from 'visibilityjs'; +import axios from '../../lib/utils/axios_utils'; +import Poll from '../../lib/utils/poll'; +import * as types from './mutation_types'; + +export const setEndpoint = ({ commit }, endpoint) => commit(types.SET_ENDPOINT, endpoint); + +export const requestReports = ({ commit }) => commit(types.REQUEST_REPORTS); + +let eTagPoll; + +export const clearEtagPoll = () => { + eTagPoll = null; +}; + +export const stopPolling = () => { + if (eTagPoll) eTagPoll.stop(); +}; + +export const restartPolling = () => { + if (eTagPoll) eTagPoll.restart(); +}; + +/** + * We need to poll the reports endpoint while they are being parsed in the Backend. + * This can take up to one minute. + * + * Poll.js will handle etag response. + * While http status code is 204, it means it's parsing, and we'll keep polling + * When http status code is 200, it means parsing is done, we can show the results & stop polling + * When http status code is 500, it means parsing went wrong and we stop polling + */ +export const fetchReports = ({ state, dispatch }) => { + dispatch('requestReports'); + + eTagPoll = new Poll({ + resource: { + getReports(endpoint) { + return axios.get(endpoint); + }, + }, + data: state.endpoint, + method: 'getReports', + successCallback: ({ data }) => dispatch('receiveReportsSuccess', data), + errorCallback: () => dispatch('receiveReportsError'), + }); + + if (!Visibility.hidden()) { + eTagPoll.makeRequest(); + } + + Visibility.change(() => { + if (!Visibility.hidden()) { + dispatch('restartPolling'); + } else { + dispatch('stopPolling'); + } + }); +}; + +export const receiveReportsSuccess = ({ commit }, response) => + commit(types.RECEIVE_REPORTS_SUCCESS, response); + +export const receiveReportsError = ({ commit }) => commit(types.RECEIVE_REPORTS_ERROR); + +// prevent babel-plugin-rewire from generating an invalid default during karma tests +export default () => {}; diff --git a/app/assets/javascripts/reports/store/index.js b/app/assets/javascripts/reports/store/index.js new file mode 100644 index 00000000000..af4f9688fb4 --- /dev/null +++ b/app/assets/javascripts/reports/store/index.js @@ -0,0 +1,13 @@ +import Vue from 'vue'; +import Vuex from 'vuex'; +import * as actions from './actions'; +import mutations from './mutations'; +import state from './state'; + +Vue.use(Vuex); + +export default () => new Vuex.Store({ + actions, + mutations, + state: state(), +}); diff --git a/app/assets/javascripts/reports/store/mutation_types.js b/app/assets/javascripts/reports/store/mutation_types.js new file mode 100644 index 00000000000..77722974c45 --- /dev/null +++ b/app/assets/javascripts/reports/store/mutation_types.js @@ -0,0 +1,5 @@ +export const SET_ENDPOINT = 'SET_ENDPOINT'; + +export const REQUEST_REPORTS = 'REQUEST_REPORTS'; +export const RECEIVE_REPORTS_SUCCESS = 'RECEIVE_REPORTS_SUCCESS'; +export const RECEIVE_REPORTS_ERROR = 'RECEIVE_REPORTS_ERROR'; diff --git a/app/assets/javascripts/reports/store/mutations.js b/app/assets/javascripts/reports/store/mutations.js new file mode 100644 index 00000000000..d9d301826cf --- /dev/null +++ b/app/assets/javascripts/reports/store/mutations.js @@ -0,0 +1,26 @@ +/* eslint-disable no-param-reassign */ +import * as types from './mutation_types'; + +export default { + [types.SET_ENDPOINT](state, endpoint) { + state.endpoint = endpoint; + }, + [types.REQUEST_REPORTS](state) { + state.isLoading = true; + }, + [types.RECEIVE_REPORTS_SUCCESS](state, response) { + + state.isLoading = false; + + state.summary.total = response.summary.total; + state.summary.resolved = response.summary.resolved; + state.summary.failed = response.summary.failed; + + state.reports = response.suites; + + }, + [types.RECEIVE_REPORTS_ERROR](state) { + state.isLoading = false; + state.hasError = true; + }, +}; diff --git a/app/assets/javascripts/reports/store/state.js b/app/assets/javascripts/reports/store/state.js new file mode 100644 index 00000000000..97f9d0a6859 --- /dev/null +++ b/app/assets/javascripts/reports/store/state.js @@ -0,0 +1,28 @@ +export default () => ({ + endpoint: null, + + isLoading: false, + hasError: false, + + summary: { + total: 0, + resolved: 0, + failed: 0, + }, + + /** + * Each report will have the following format: + * { + * name: {String}, + * summary: { + * total: {Number}, + * resolved: {Number}, + * failed: {Number}, + * }, + * new_failures: {Array.<Object>}, + * resolved_failures: {Array.<Object>}, + * existing_failures: {Array.<Object>}, + * } + */ + reports: [], +}); diff --git a/app/assets/javascripts/sidebar/components/assignees/assignees.vue b/app/assets/javascripts/sidebar/components/assignees/assignees.vue index d22a1e1ac66..dd155c133ce 100644 --- a/app/assets/javascripts/sidebar/components/assignees/assignees.vue +++ b/app/assets/javascripts/sidebar/components/assignees/assignees.vue @@ -187,7 +187,7 @@ export default { <template v-else-if="hasOneUser"> <a :href="assigneeUrl(firstUser)" - class="author_link bold" + class="author-link bold" > <img :alt="assigneeAlt(firstUser)" diff --git a/app/assets/javascripts/sidebar/components/participants/participants.vue b/app/assets/javascripts/sidebar/components/participants/participants.vue index 33dd6c981b6..56d57f6aac8 100644 --- a/app/assets/javascripts/sidebar/components/participants/participants.vue +++ b/app/assets/javascripts/sidebar/components/participants/participants.vue @@ -120,7 +120,7 @@ > <a :href="participant.web_url" - class="author_link" + class="author-link" > <user-avatar-image :lazy="true" diff --git a/app/assets/javascripts/users_select.js b/app/assets/javascripts/users_select.js index e3d7645040d..e19bbbacf4d 100644 --- a/app/assets/javascripts/users_select.js +++ b/app/assets/javascripts/users_select.js @@ -206,8 +206,8 @@ function UsersSelect(currentUser, els, options = {}) { return $collapsedSidebar.html(collapsedAssigneeTemplate(user)); }); }; - collapsedAssigneeTemplate = _.template('<% if( avatar ) { %> <a class="author_link" href="/<%- username %>"> <img width="24" class="avatar avatar-inline s24" alt="" src="<%- avatar %>"> </a> <% } else { %> <i class="fa fa-user"></i> <% } %>'); - assigneeTemplate = _.template('<% if (username) { %> <a class="author_link bold" href="/<%- username %>"> <% if( avatar ) { %> <img width="32" class="avatar avatar-inline s32" alt="" src="<%- avatar %>"> <% } %> <span class="author"><%- name %></span> <span class="username"> @<%- username %> </span> </a> <% } else { %> <span class="no-value assign-yourself"> No assignee - <a href="#" class="js-assign-yourself"> assign yourself </a> </span> <% } %>'); + collapsedAssigneeTemplate = _.template('<% if( avatar ) { %> <a class="author-link" href="/<%- username %>"> <img width="24" class="avatar avatar-inline s24" alt="" src="<%- avatar %>"> </a> <% } else { %> <i class="fa fa-user"></i> <% } %>'); + assigneeTemplate = _.template('<% if (username) { %> <a class="author-link bold" href="/<%- username %>"> <% if( avatar ) { %> <img width="32" class="avatar avatar-inline s32" alt="" src="<%- avatar %>"> <% } %> <span class="author"><%- name %></span> <span class="username"> @<%- username %> </span> </a> <% } else { %> <span class="no-value assign-yourself"> No assignee - <a href="#" class="js-assign-yourself"> assign yourself </a> </span> <% } %>'); return $dropdown.glDropdown({ showMenuAbove: showMenuAbove, data: function(term, callback) { diff --git a/app/assets/javascripts/vue_shared/components/clipboard_button.vue b/app/assets/javascripts/vue_shared/components/clipboard_button.vue index dc5760bce28..d272bf3f55f 100644 --- a/app/assets/javascripts/vue_shared/components/clipboard_button.vue +++ b/app/assets/javascripts/vue_shared/components/clipboard_button.vue @@ -13,12 +13,19 @@ * /> */ import tooltip from '../directives/tooltip'; +import Icon from '../components/icon.vue'; export default { name: 'ClipboardButton', + directives: { tooltip, }, + + components: { + Icon, + }, + props: { text: { type: String, @@ -58,10 +65,6 @@ export default { type="button" class="btn" > - <i - aria-hidden="true" - class="fa fa-clipboard" - > - </i> + <icon name="duplicate" /> </button> </template> 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 b1c2df54ef6..f44d361c47e 100644 --- a/app/assets/javascripts/vue_shared/components/stacked_progress_bar.vue +++ b/app/assets/javascripts/vue_shared/components/stacked_progress_bar.vue @@ -1,4 +1,5 @@ <script> +import { roundOffFloat } from '~/lib/utils/common_utils'; import tooltip from '~/vue_shared/directives/tooltip'; export default { @@ -70,7 +71,7 @@ export default { }, methods: { getPercent(count) { - return Math.ceil((count / this.totalCount) * 100); + return roundOffFloat((count / this.totalCount) * 100, 1); }, barStyle(percent) { return `width: ${percent}%;`; diff --git a/app/assets/stylesheets/framework/avatar.scss b/app/assets/stylesheets/framework/avatar.scss index c1ec11e434a..94fa7993133 100644 --- a/app/assets/stylesheets/framework/avatar.scss +++ b/app/assets/stylesheets/framework/avatar.scss @@ -7,7 +7,7 @@ .avatar-circle { float: left; margin-right: 15px; - border-radius: $avatar_radius; + border-radius: $avatar-radius; border: 1px solid $avatar-border; &.s16 { @include avatar-size(16px, 6px); } &.s18 { @include avatar-size(18px, 6px); } @@ -110,7 +110,7 @@ color: $white-light; border: 1px solid $avatar-border; border-radius: 1em; - font-family: $regular_font; + font-family: $regular-font; font-size: 9px; line-height: 16px; text-align: center; diff --git a/app/assets/stylesheets/framework/buttons.scss b/app/assets/stylesheets/framework/buttons.scss index 523fcb05a87..646cedd79ed 100644 --- a/app/assets/stylesheets/framework/buttons.scss +++ b/app/assets/stylesheets/framework/buttons.scss @@ -294,6 +294,10 @@ .btn-clipboard { border: 0; padding: 0 5px; + + svg { + top: auto; + } } .input-group-prepend, diff --git a/app/assets/stylesheets/framework/common.scss b/app/assets/stylesheets/framework/common.scss index 218e37602dd..637587de597 100644 --- a/app/assets/stylesheets/framework/common.scss +++ b/app/assets/stylesheets/framework/common.scss @@ -113,8 +113,6 @@ hr { .item-title { font-weight: $gl-font-weight-bold; } -/** FLASH message **/ -.author_link, .author-link { color: $gl-link-color; } diff --git a/app/assets/stylesheets/framework/forms.scss b/app/assets/stylesheets/framework/forms.scss index a10ff3eecb3..d7149d93622 100644 --- a/app/assets/stylesheets/framework/forms.scss +++ b/app/assets/stylesheets/framework/forms.scss @@ -80,7 +80,7 @@ label { .form-control { height: 29px; background: $white-light; - font-family: $monospace_font; + font-family: $monospace-font; } .input-group-prepend .btn, diff --git a/app/assets/stylesheets/framework/highlight.scss b/app/assets/stylesheets/framework/highlight.scss index 813a1711ea2..452e946f95f 100644 --- a/app/assets/stylesheets/framework/highlight.scss +++ b/app/assets/stylesheets/framework/highlight.scss @@ -9,8 +9,8 @@ padding: 10px 0; border: 0; border-radius: 0; - font-family: $monospace_font; - font-size: $code_font_size; + font-family: $monospace-font; + font-size: $code-font-size; line-height: 19px; margin: 0; overflow: auto; @@ -22,7 +22,7 @@ code { display: inline-block; min-width: 100%; - font-family: $monospace_font; + font-family: $monospace-font; white-space: normal; word-wrap: normal; padding: 0; @@ -44,7 +44,7 @@ float: left; a { - font-family: $monospace_font; + font-family: $monospace-font; display: block; font-size: $code_font_size !important; min-height: 19px; diff --git a/app/assets/stylesheets/framework/jquery.scss b/app/assets/stylesheets/framework/jquery.scss index 300ba4f2de6..d1360a0c0eb 100644 --- a/app/assets/stylesheets/framework/jquery.scss +++ b/app/assets/stylesheets/framework/jquery.scss @@ -1,5 +1,5 @@ .ui-widget { - font-family: $regular_font; + font-family: $regular-font; font-size: $font-size-base; .ui-state-default { diff --git a/app/assets/stylesheets/framework/lists.scss b/app/assets/stylesheets/framework/lists.scss index d54490c87c6..4b67eab05b3 100644 --- a/app/assets/stylesheets/framework/lists.scss +++ b/app/assets/stylesheets/framework/lists.scss @@ -259,7 +259,7 @@ ul.controls { margin-right: 0; } - .author_link { + .author-link { .avatar-inline { margin-left: 0; margin-right: 0; @@ -270,7 +270,7 @@ ul.controls { .issuable-pipeline-broken a, .issuable-pipeline-status a, - .author_link { + .author-link { display: flex; } } diff --git a/app/assets/stylesheets/framework/mixins.scss b/app/assets/stylesheets/framework/mixins.scss index 76ebfc22ef7..11d332be1be 100644 --- a/app/assets/stylesheets/framework/mixins.scss +++ b/app/assets/stylesheets/framework/mixins.scss @@ -3,13 +3,13 @@ * Mixins with fixed values */ -@mixin str-truncated($max_width: 82%) { +@mixin str-truncated($max-width: 82%) { display: inline-block; overflow: hidden; text-overflow: ellipsis; vertical-align: top; white-space: nowrap; - max-width: $max_width; + max-width: $max-width; } /* diff --git a/app/assets/stylesheets/framework/sidebar.scss b/app/assets/stylesheets/framework/sidebar.scss index 8c716400913..c4dbcf2ddc9 100644 --- a/app/assets/stylesheets/framework/sidebar.scss +++ b/app/assets/stylesheets/framework/sidebar.scss @@ -33,11 +33,11 @@ @include media-breakpoint-up(sm) { &:not(.wiki-sidebar):not(.build-sidebar):not(.issuable-bulk-update-sidebar) .content-wrapper { - padding-right: $gutter_collapsed_width; + padding-right: $gutter-collapsed-width; } .merge-request-tabs-holder.affix { - right: $gutter_collapsed_width; + right: $gutter-collapsed-width; } } @@ -67,21 +67,21 @@ @include media-breakpoint-only(sm) { &:not(.wiki-sidebar):not(.build-sidebar):not(.issuable-bulk-update-sidebar) .content-wrapper { - padding-right: $gutter_collapsed_width; + padding-right: $gutter-collapsed-width; } } @include media-breakpoint-up(md) { .content-wrapper { - padding-right: $gutter_width; + padding-right: $gutter-width; } &:not(.with-overlay) .merge-request-tabs-holder.affix { - right: $gutter_width; + right: $gutter-width; } &.with-overlay .merge-request-tabs-holder.affix { - right: $gutter_collapsed_width; + right: $gutter-collapsed-width; } } } diff --git a/app/assets/stylesheets/framework/stacked_progress_bar.scss b/app/assets/stylesheets/framework/stacked_progress_bar.scss index 528ba53a48b..29a2d5881f7 100644 --- a/app/assets/stylesheets/framework/stacked_progress_bar.scss +++ b/app/assets/stylesheets/framework/stacked_progress_bar.scss @@ -10,7 +10,7 @@ .status-neutral, .status-red, { height: 100%; - min-width: 30px; + min-width: 40px; padding: 0 5px; font-size: $tooltip-font-size; font-weight: normal; diff --git a/app/assets/stylesheets/framework/typography.scss b/app/assets/stylesheets/framework/typography.scss index 9874c928604..56307777a72 100644 --- a/app/assets/stylesheets/framework/typography.scss +++ b/app/assets/stylesheets/framework/typography.scss @@ -44,7 +44,7 @@ // Single code lines should wrap code { - font-family: $monospace_font; + font-family: $monospace-font; white-space: pre-wrap; word-wrap: normal; } @@ -321,7 +321,7 @@ h6 { /** CODE **/ pre { - font-family: $monospace_font; + font-family: $monospace-font; display: block; padding: $gl-padding-8; margin: 0 0 $gl-padding-8; @@ -342,7 +342,7 @@ code { } .monospace { - font-family: $monospace_font; + font-family: $monospace-font; } .weight-normal { @@ -381,7 +381,7 @@ code { * */ textarea.js-gfm-input { - font-family: $monospace_font; + font-family: $monospace-font; font-size: 13px; } diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss index 6c2fdbe0608..efc54196b75 100644 --- a/app/assets/stylesheets/framework/variables.scss +++ b/app/assets/stylesheets/framework/variables.scss @@ -2,9 +2,9 @@ * Layout */ $grid-size: 8px; -$gutter_collapsed_width: 62px; -$gutter_width: 290px; -$gutter_inner_width: 250px; +$gutter-collapsed-width: 62px; +$gutter-width: 290px; +$gutter-inner-width: 250px; $sidebar-transition-duration: 0.3s; $sidebar-breakpoint: 1024px; $default-transition-duration: 0.15s; @@ -233,8 +233,8 @@ $md-area-border: #ddd; /* * Code */ -$code_font_size: 90%; -$code_line_height: 1.6; +$code-font-size: 90%; +$code-line-height: 1.6; /* * Tooltips @@ -371,9 +371,9 @@ $diff-jagged-border-gradient-color: darken($white-normal, 8%); /* * Fonts */ -$monospace_font: 'Menlo', 'DejaVu Sans Mono', 'Liberation Mono', 'Consolas', 'Ubuntu Mono', +$monospace-font: 'Menlo', 'DejaVu Sans Mono', 'Liberation Mono', 'Consolas', 'Ubuntu Mono', 'Courier New', 'andale mono', 'lucida console', monospace; -$regular_font: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, +$regular-font: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; /* @@ -526,7 +526,7 @@ $issue-board-list-difference-md: $issue-board-list-difference-sm + $issue-boards /* * Avatar */ -$avatar_radius: 50%; +$avatar-radius: 50%; $avatar-border: $gray-normal; $avatar-border-hover: $gray-darker; $avatar-background: $gray-lightest; @@ -830,8 +830,8 @@ $secondary: $gray-light; $input-disabled-bg: $gray-light; $input-border-color: $theme-gray-200; $input-color: $gl-text-color; -$font-family-sans-serif: $regular_font; -$font-family-monospace: $monospace_font; +$font-family-sans-serif: $regular-font; +$font-family-monospace: $monospace-font; $input-line-height: 20px; $btn-line-height: 20px; $table-accent-bg: $gray-light; diff --git a/app/assets/stylesheets/mailers/highlighted_diff_email.scss b/app/assets/stylesheets/mailers/highlighted_diff_email.scss index 1835c4364d3..8b234a5a656 100644 --- a/app/assets/stylesheets/mailers/highlighted_diff_email.scss +++ b/app/assets/stylesheets/mailers/highlighted_diff_email.scss @@ -77,13 +77,13 @@ $highlighted-gc-bg: #eaf2f5; .code { background-color: $white-light; font-family: monospace; - font-size: $code_font_size; + font-size: $code-font-size; -premailer-cellpadding: 0; -premailer-cellspacing: 0; -premailer-width: 100%; > tr { - line-height: $code_line_height; + line-height: $code-line-height; } } diff --git a/app/assets/stylesheets/pages/boards.scss b/app/assets/stylesheets/pages/boards.scss index 5de53892fac..7347da2ae61 100644 --- a/app/assets/stylesheets/pages/boards.scss +++ b/app/assets/stylesheets/pages/boards.scss @@ -63,7 +63,7 @@ width: 100%; &.is-compact { - width: calc(100% - #{$gutter_width}); + width: calc(100% - #{$gutter-width}); } } } diff --git a/app/assets/stylesheets/pages/commits.scss b/app/assets/stylesheets/pages/commits.scss index f75be4e01cd..9b51c54a0fc 100644 --- a/app/assets/stylesheets/pages/commits.scss +++ b/app/assets/stylesheets/pages/commits.scss @@ -79,7 +79,7 @@ .commit-message-container { background-color: $body-bg; position: relative; - font-family: $monospace_font; + font-family: $monospace-font; $left: 12px; overflow: hidden; // See https://gitlab.com/gitlab-org/gitlab-ce/issues/13987 .max-width-marker { @@ -205,7 +205,7 @@ > .ci-status-link, > .btn, > .commit-sha-group { - margin-left: $gl-padding-8; + margin-left: $gl-padding; } } @@ -235,10 +235,6 @@ fill: $gl-text-color-secondary; } - .fa-clipboard { - color: $gl-text-color-secondary; - } - :first-child { border-bottom-left-radius: $border-radius-default; border-top-left-radius: $border-radius-default; diff --git a/app/assets/stylesheets/pages/cycle_analytics.scss b/app/assets/stylesheets/pages/cycle_analytics.scss index a22c666a525..e2c0a7a6225 100644 --- a/app/assets/stylesheets/pages/cycle_analytics.scss +++ b/app/assets/stylesheets/pages/cycle_analytics.scss @@ -368,7 +368,7 @@ .fa { color: $gl-text-color-secondary; - font-size: $code_font_size; + font-size: $code-font-size; } } } diff --git a/app/assets/stylesheets/pages/detail_page.scss b/app/assets/stylesheets/pages/detail_page.scss index 2e007c52592..37ed5ae674a 100644 --- a/app/assets/stylesheets/pages/detail_page.scss +++ b/app/assets/stylesheets/pages/detail_page.scss @@ -10,7 +10,7 @@ } .issue_created_ago, - .author_link { + .author-link { white-space: nowrap; } diff --git a/app/assets/stylesheets/pages/diff.scss b/app/assets/stylesheets/pages/diff.scss index 5e39bbb9890..b616357bb8d 100644 --- a/app/assets/stylesheets/pages/diff.scss +++ b/app/assets/stylesheets/pages/diff.scss @@ -56,7 +56,7 @@ table { width: 100%; - font-family: $monospace_font; + font-family: $monospace-font; border: 0; border-collapse: separate; margin: 0; @@ -73,8 +73,8 @@ } .line_holder td { - line-height: $code_line_height; - font-size: $code_font_size; + line-height: $code-line-height; + font-size: $code-font-size; &.noteable_line { position: relative; diff --git a/app/assets/stylesheets/pages/editor.scss b/app/assets/stylesheets/pages/editor.scss index 437621299e0..ddd1f8cc98a 100644 --- a/app/assets/stylesheets/pages/editor.scss +++ b/app/assets/stylesheets/pages/editor.scss @@ -84,7 +84,7 @@ .soft-wrap-toggle { display: inline-block; vertical-align: top; - font-family: $regular_font; + font-family: $regular-font; } .soft-wrap-toggle { diff --git a/app/assets/stylesheets/pages/environments.scss b/app/assets/stylesheets/pages/environments.scss index 8915b323b3c..8a074017344 100644 --- a/app/assets/stylesheets/pages/environments.scss +++ b/app/assets/stylesheets/pages/environments.scss @@ -478,7 +478,7 @@ } .deploy-info-text-link { - font-family: $monospace_font; + font-family: $monospace-font; fill: $gl-link-color; &:hover { diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss index f9fd9f1ab8b..797b106de23 100644 --- a/app/assets/stylesheets/pages/issuable.scss +++ b/app/assets/stylesheets/pages/issuable.scss @@ -166,7 +166,7 @@ border-bottom: 1px solid $border-gray-normal; // This prevents the mess when resizing the sidebar // of elements repositioning themselves.. - width: $gutter_inner_width; + width: $gutter-inner-width; // -- &.issuable-sidebar-header { @@ -197,7 +197,7 @@ } &.assignee { - .author_link { + .author-link { display: block; padding-left: 42px; position: relative; @@ -290,7 +290,7 @@ } &.right-sidebar-expanded { - width: $gutter_width; + width: $gutter-width; .value { line-height: 1; @@ -377,11 +377,11 @@ display: block; } - width: $gutter_collapsed_width; + width: $gutter-collapsed-width; padding: 0; .block { - width: $gutter_collapsed_width - 2px; + width: $gutter-collapsed-width - 2px; padding: 15px 0 0; border-bottom: 0; overflow: hidden; @@ -486,7 +486,7 @@ padding-bottom: 0; margin-bottom: 10px; - .author_link { + .author-link { padding-left: 0; .avatar { @@ -595,7 +595,7 @@ margin: 16px 0 0; font-size: 85%; - .author_link { + .author-link { color: $gray-darkest; } } @@ -620,7 +620,7 @@ padding-right: 0; } - .author_link { + .author-link { display: block; } diff --git a/app/assets/stylesheets/pages/issues.scss b/app/assets/stylesheets/pages/issues.scss index 19fb99bfa93..212e5979273 100644 --- a/app/assets/stylesheets/pages/issues.scss +++ b/app/assets/stylesheets/pages/issues.scss @@ -12,7 +12,7 @@ } .issuable-meta { - .author_link { + .author-link { display: inline-block; } diff --git a/app/assets/stylesheets/pages/merge_conflicts.scss b/app/assets/stylesheets/pages/merge_conflicts.scss index e76525fdbf6..d26659701e1 100644 --- a/app/assets/stylesheets/pages/merge_conflicts.scss +++ b/app/assets/stylesheets/pages/merge_conflicts.scss @@ -1,167 +1,162 @@ // Disabled to use the color map for creating color schemes // scss-lint:disable ColorVariable $colors: ( - white_header_head_neutral : #e1fad7, - white_line_head_neutral : #effdec, - white_button_head_neutral : #9adb84, + white-header-head-neutral : #e1fad7, + white-line-head-neutral : #effdec, + white-button-head-neutral : #9adb84, - white_header_head_chosen : #baf0a8, - white_line_head_chosen : #e1fad7, - white_button_head_chosen : #52c22d, + white-header-head-chosen : #baf0a8, + white-line-head-chosen : #e1fad7, + white-button-head-chosen : #52c22d, - white_header_origin_neutral : #e0f0ff, - white_line_origin_neutral : #f2f9ff, - white_button_origin_neutral : #87c2fa, + white-header-origin-neutral : #e0f0ff, + white-line-origin-neutral : #f2f9ff, + white-button-origin-neutral : #87c2fa, - white_header_origin_chosen : #add8ff, - white_line_origin_chosen : #e0f0ff, - white_button_origin_chosen : #268ced, + white-header-origin-chosen : #add8ff, + white-line-origin-chosen : #e0f0ff, + white-button-origin-chosen : #268ced, - white_header_not_chosen : #f0f0f0, - white_line_not_chosen : $gray-light, + white-header-not-chosen : #f0f0f0, + white-line-not-chosen : $gray-light, + dark-header-head-neutral : rgba(#3f3, .2), + dark-line-head-neutral : rgba(#3f3, .1), + dark-button-head-neutral : #40874f, - dark_header_head_neutral : rgba(#3f3, .2), - dark_line_head_neutral : rgba(#3f3, .1), - dark_button_head_neutral : #40874f, + dark-header-head-chosen : rgba(#3f3, .33), + dark-line-head-chosen : rgba(#3f3, .2), + dark-button-head-chosen : #258537, - dark_header_head_chosen : rgba(#3f3, .33), - dark_line_head_chosen : rgba(#3f3, .2), - dark_button_head_chosen : #258537, + dark-header-origin-neutral : rgba(#2878c9, .4), + dark-line-origin-neutral : rgba(#2878c9, .3), + dark-button-origin-neutral : #2a5c8c, - dark_header_origin_neutral : rgba(#2878c9, .4), - dark_line_origin_neutral : rgba(#2878c9, .3), - dark_button_origin_neutral : #2a5c8c, + dark-header-origin-chosen : rgba(#2878c9, .6), + dark-line-origin-chosen : rgba(#2878c9, .4), + dark-button-origin-chosen : #1d6cbf, - dark_header_origin_chosen : rgba(#2878c9, .6), - dark_line_origin_chosen : rgba(#2878c9, .4), - dark_button_origin_chosen : #1d6cbf, + dark-header-not-chosen : rgba(#fff, .25), + dark-line-not-chosen : rgba(#fff, .1), - dark_header_not_chosen : rgba(#fff, .25), - dark_line_not_chosen : rgba(#fff, .1), + monokai-header-head-neutral : rgba(#a6e22e, .25), + monokai-line-head-neutral : rgba(#a6e22e, .1), + monokai-button-head-neutral : #376b20, + monokai-header-head-chosen : rgba(#a6e22e, .4), + monokai-line-head-chosen : rgba(#a6e22e, .25), + monokai-button-head-chosen : #39800d, - monokai_header_head_neutral : rgba(#a6e22e, .25), - monokai_line_head_neutral : rgba(#a6e22e, .1), - monokai_button_head_neutral : #376b20, + monokai-header-origin-neutral : rgba(#60d9f1, .35), + monokai-line-origin-neutral : rgba(#60d9f1, .15), + monokai-button-origin-neutral : #38848c, - monokai_header_head_chosen : rgba(#a6e22e, .4), - monokai_line_head_chosen : rgba(#a6e22e, .25), - monokai_button_head_chosen : #39800d, + monokai-header-origin-chosen : rgba(#60d9f1, .5), + monokai-line-origin-chosen : rgba(#60d9f1, .35), + monokai-button-origin-chosen : #3ea4b2, - monokai_header_origin_neutral : rgba(#60d9f1, .35), - monokai_line_origin_neutral : rgba(#60d9f1, .15), - monokai_button_origin_neutral : #38848c, + monokai-header-not-chosen : rgba(#76715d, .24), + monokai-line-not-chosen : rgba(#76715d, .1), - monokai_header_origin_chosen : rgba(#60d9f1, .5), - monokai_line_origin_chosen : rgba(#60d9f1, .35), - monokai_button_origin_chosen : #3ea4b2, + solarized-light-header-head-neutral : rgba(#859900, .37), + solarized-light-line-head-neutral : rgba(#859900, .2), + solarized-light-button-head-neutral : #afb262, - monokai_header_not_chosen : rgba(#76715d, .24), - monokai_line_not_chosen : rgba(#76715d, .1), + solarized-light-header-head-chosen : rgba(#859900, .5), + solarized-light-line-head-chosen : rgba(#859900, .37), + solarized-light-button-head-chosen : #94993d, + solarized-light-header-origin-neutral : rgba(#2878c9, .37), + solarized-light-line-origin-neutral : rgba(#2878c9, .15), + solarized-light-button-origin-neutral : #60a1bf, - solarized_light_header_head_neutral : rgba(#859900, .37), - solarized_light_line_head_neutral : rgba(#859900, .2), - solarized_light_button_head_neutral : #afb262, + solarized-light-header-origin-chosen : rgba(#2878c9, .6), + solarized-light-line-origin-chosen : rgba(#2878c9, .37), + solarized-light-button-origin-chosen : #2482b2, - solarized_light_header_head_chosen : rgba(#859900, .5), - solarized_light_line_head_chosen : rgba(#859900, .37), - solarized_light_button_head_chosen : #94993d, + solarized-light-header-not-chosen : rgba(#839496, .37), + solarized-light-line-not-chosen : rgba(#839496, .2), - solarized_light_header_origin_neutral : rgba(#2878c9, .37), - solarized_light_line_origin_neutral : rgba(#2878c9, .15), - solarized_light_button_origin_neutral : #60a1bf, + solarized-dark-header-head-neutral : rgba(#859900, .35), + solarized-dark-line-head-neutral : rgba(#859900, .15), + solarized-dark-button-head-neutral : #376b20, - solarized_light_header_origin_chosen : rgba(#2878c9, .6), - solarized_light_line_origin_chosen : rgba(#2878c9, .37), - solarized_light_button_origin_chosen : #2482b2, + solarized-dark-header-head-chosen : rgba(#859900, .5), + solarized-dark-line-head-chosen : rgba(#859900, .35), + solarized-dark-button-head-chosen : #39800d, - solarized_light_header_not_chosen : rgba(#839496, .37), - solarized_light_line_not_chosen : rgba(#839496, .2), + solarized-dark-header-origin-neutral : rgba(#2878c9, .35), + solarized-dark-line-origin-neutral : rgba(#2878c9, .15), + solarized-dark-button-origin-neutral : #086799, + solarized-dark-header-origin-chosen : rgba(#2878c9, .6), + solarized-dark-line-origin-chosen : rgba(#2878c9, .35), + solarized-dark-button-origin-chosen : #0082cc, - solarized_dark_header_head_neutral : rgba(#859900, .35), - solarized_dark_line_head_neutral : rgba(#859900, .15), - solarized_dark_button_head_neutral : #376b20, - - solarized_dark_header_head_chosen : rgba(#859900, .5), - solarized_dark_line_head_chosen : rgba(#859900, .35), - solarized_dark_button_head_chosen : #39800d, - - solarized_dark_header_origin_neutral : rgba(#2878c9, .35), - solarized_dark_line_origin_neutral : rgba(#2878c9, .15), - solarized_dark_button_origin_neutral : #086799, - - solarized_dark_header_origin_chosen : rgba(#2878c9, .6), - solarized_dark_line_origin_chosen : rgba(#2878c9, .35), - solarized_dark_button_origin_chosen : #0082cc, - - solarized_dark_header_not_chosen : rgba(#839496, .25), - solarized_dark_line_not_chosen : rgba(#839496, .15) + solarized-dark-header-not-chosen : rgba(#839496, .25), + solarized-dark-line-not-chosen : rgba(#839496, .15) ); // scss-lint:enable ColorVariable - @mixin color-scheme($color) { .header.line_content, .diff-line-num { &.origin { - background-color: map-get($colors, #{$color}_header_origin_neutral); - border-color: map-get($colors, #{$color}_header_origin_neutral); + background-color: map-get($colors, #{$color}-header-origin-neutral); + border-color: map-get($colors, #{$color}-header-origin-neutral); button { - background-color: map-get($colors, #{$color}_button_origin_neutral); - border-color: darken(map-get($colors, #{$color}_button_origin_neutral), 15); + background-color: map-get($colors, #{$color}-button-origin-neutral); + border-color: darken(map-get($colors, #{$color}-button-origin-neutral), 15); } &.selected { - background-color: map-get($colors, #{$color}_header_origin_chosen); - border-color: map-get($colors, #{$color}_header_origin_chosen); + background-color: map-get($colors, #{$color}-header-origin-chosen); + border-color: map-get($colors, #{$color}-header-origin-chosen); button { - background-color: map-get($colors, #{$color}_button_origin_chosen); - border-color: darken(map-get($colors, #{$color}_button_origin_chosen), 15); + background-color: map-get($colors, #{$color}-button-origin-chosen); + border-color: darken(map-get($colors, #{$color}-button-origin-chosen), 15); } } &.unselected { - background-color: map-get($colors, #{$color}_header_not_chosen); - border-color: map-get($colors, #{$color}_header_not_chosen); + background-color: map-get($colors, #{$color}-header-not-chosen); + border-color: map-get($colors, #{$color}-header-not-chosen); button { - background-color: lighten(map-get($colors, #{$color}_button_origin_neutral), 15); - border-color: map-get($colors, #{$color}_button_origin_neutral); + background-color: lighten(map-get($colors, #{$color}-button-origin-neutral), 15); + border-color: map-get($colors, #{$color}-button-origin-neutral); } } } &.head { - background-color: map-get($colors, #{$color}_header_head_neutral); - border-color: map-get($colors, #{$color}_header_head_neutral); + background-color: map-get($colors, #{$color}-header-head-neutral); + border-color: map-get($colors, #{$color}-header-head-neutral); button { - background-color: map-get($colors, #{$color}_button_head_neutral); - border-color: darken(map-get($colors, #{$color}_button_head_neutral), 15); + background-color: map-get($colors, #{$color}-button-head-neutral); + border-color: darken(map-get($colors, #{$color}-button-head-neutral), 15); } &.selected { - background-color: map-get($colors, #{$color}_header_head_chosen); - border-color: map-get($colors, #{$color}_header_head_chosen); + background-color: map-get($colors, #{$color}-header-head-chosen); + border-color: map-get($colors, #{$color}-header-head-chosen); button { - background-color: map-get($colors, #{$color}_button_head_chosen); - border-color: darken(map-get($colors, #{$color}_button_head_chosen), 15); + background-color: map-get($colors, #{$color}-button-head-chosen); + border-color: darken(map-get($colors, #{$color}-button-head-chosen), 15); } } &.unselected { - background-color: map-get($colors, #{$color}_header_not_chosen); - border-color: map-get($colors, #{$color}_header_not_chosen); + background-color: map-get($colors, #{$color}-header-not-chosen); + border-color: map-get($colors, #{$color}-header-not-chosen); button { - background-color: lighten(map-get($colors, #{$color}_button_head_neutral), 15); - border-color: map-get($colors, #{$color}_button_head_neutral); + background-color: lighten(map-get($colors, #{$color}-button-head-neutral), 15); + border-color: map-get($colors, #{$color}-button-head-neutral); } } } @@ -169,32 +164,31 @@ $colors: ( .line_content { &.origin { - background-color: map-get($colors, #{$color}_line_origin_neutral); + background-color: map-get($colors, #{$color}-line-origin-neutral); &.selected { - background-color: map-get($colors, #{$color}_line_origin_chosen); + background-color: map-get($colors, #{$color}-line-origin-chosen); } &.unselected { - background-color: map-get($colors, #{$color}_line_not_chosen); + background-color: map-get($colors, #{$color}-line-not-chosen); } } &.head { - background-color: map-get($colors, #{$color}_line_head_neutral); + background-color: map-get($colors, #{$color}-line-head-neutral); &.selected { - background-color: map-get($colors, #{$color}_line_head_chosen); + background-color: map-get($colors, #{$color}-line-head-chosen); } &.unselected { - background-color: map-get($colors, #{$color}_line_not_chosen); + background-color: map-get($colors, #{$color}-line-not-chosen); } } } } - #conflicts { .white { @@ -210,11 +204,11 @@ $colors: ( } .solarized-light { - @include color-scheme('solarized_light') + @include color-scheme('solarized-light') } .solarized-dark { - @include color-scheme('solarized_dark') + @include color-scheme('solarized-dark') } .diff-wrap-lines .line_content { diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss index c8349a4ef79..7bd0f0bf1e0 100644 --- a/app/assets/stylesheets/pages/merge_requests.scss +++ b/app/assets/stylesheets/pages/merge_requests.scss @@ -208,7 +208,7 @@ position: absolute; content: '...'; right: 0; - font-family: $regular_font; + font-family: $regular-font; background-color: $gray-light; } } diff --git a/app/assets/stylesheets/pages/note_form.scss b/app/assets/stylesheets/pages/note_form.scss index 5e5696b1602..dcf590e7331 100644 --- a/app/assets/stylesheets/pages/note_form.scss +++ b/app/assets/stylesheets/pages/note_form.scss @@ -42,7 +42,7 @@ display: block; padding: 10px 0; color: $gl-text-color; - font-family: $regular_font; + font-family: $regular-font; border: 0; &:focus { diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss index 32d14049067..7fc2936c5e6 100644 --- a/app/assets/stylesheets/pages/notes.scss +++ b/app/assets/stylesheets/pages/notes.scss @@ -328,7 +328,7 @@ ul.notes { } .notes_holder { - font-family: $regular_font; + font-family: $regular-font; td { border: 1px solid $white-normal; @@ -403,7 +403,7 @@ ul.notes { } } - .author_link { + .author-link { color: $gl-text-color; } } diff --git a/app/assets/stylesheets/pages/repo.scss b/app/assets/stylesheets/pages/repo.scss index 8b1227b9131..2d76f0ce004 100644 --- a/app/assets/stylesheets/pages/repo.scss +++ b/app/assets/stylesheets/pages/repo.scss @@ -961,7 +961,7 @@ overflow: hidden; .note-textarea { - font-family: $monospace_font; + font-family: $monospace-font; } } diff --git a/app/assets/stylesheets/snippets.scss b/app/assets/stylesheets/snippets.scss index 0d6b0735f70..64110f9c3a0 100644 --- a/app/assets/stylesheets/snippets.scss +++ b/app/assets/stylesheets/snippets.scss @@ -6,9 +6,9 @@ $border-style: 1px solid $border-color; - font-family: $regular_font; + font-family: $regular-font; font-size: $gl-font-size; - line-height: $code_line_height; + line-height: $code-line-height; color: $gl-text-color; margin: 20px; font-weight: 200; @@ -48,9 +48,9 @@ padding: 10px; border: 0; border-radius: 0; - font-family: $monospace_font; - font-size: $code_font_size; - line-height: $code_line_height; + font-family: $monospace-font; + font-size: $code-font-size; + line-height: $code-line-height; margin: 0; overflow: auto; overflow-y: hidden; @@ -66,10 +66,10 @@ float: left; .diff-line-num { - font-family: $monospace_font; + font-family: $monospace-font; display: block; - font-size: $code_font_size; - min-height: $code_line_height; + font-size: $code-font-size; + min-height: $code-line-height; white-space: nowrap; color: $black-transparent; min-width: 30px; diff --git a/app/controllers/concerns/lfs_request.rb b/app/controllers/concerns/lfs_request.rb index 79ee5b2f91e..4584ff782a3 100644 --- a/app/controllers/concerns/lfs_request.rb +++ b/app/controllers/concerns/lfs_request.rb @@ -71,7 +71,22 @@ module LfsRequest def lfs_download_access? return false unless project.lfs_enabled? - ci? || lfs_deploy_token? || user_can_download_code? || build_can_download_code? + ci? || lfs_deploy_token? || user_can_download_code? || build_can_download_code? || deploy_token_can_download_code? + end + + def deploy_token_can_download_code? + deploy_token_present? && + deploy_token.project == project && + deploy_token.active? && + deploy_token.read_repository? + end + + def deploy_token_present? + user && user.is_a?(DeployToken) + end + + def deploy_token + user end def lfs_upload_access? @@ -86,7 +101,7 @@ module LfsRequest end def user_can_download_code? - has_authentication_ability?(:download_code) && can?(user, :download_code, project) + has_authentication_ability?(:download_code) && can?(user, :download_code, project) && !deploy_token_present? end def build_can_download_code? diff --git a/app/controllers/import/gitlab_controller.rb b/app/controllers/import/gitlab_controller.rb index fccbdbca0f6..53f70446d95 100644 --- a/app/controllers/import/gitlab_controller.rb +++ b/app/controllers/import/gitlab_controller.rb @@ -1,4 +1,7 @@ class Import::GitlabController < Import::BaseController + MAX_PROJECT_PAGES = 15 + PER_PAGE_PROJECTS = 100 + before_action :verify_gitlab_import_enabled before_action :gitlab_auth, except: :callback @@ -10,7 +13,7 @@ class Import::GitlabController < Import::BaseController end def status - @repos = client.projects + @repos = client.projects(starting_page: 1, page_limit: MAX_PROJECT_PAGES, per_page: PER_PAGE_PROJECTS) @already_added_projects = find_already_added_projects('gitlab') already_added_projects_names = @already_added_projects.pluck(:import_source) diff --git a/app/controllers/profiles_controller.rb b/app/controllers/profiles_controller.rb index 074db361949..56a7b766b77 100644 --- a/app/controllers/profiles_controller.rb +++ b/app/controllers/profiles_controller.rb @@ -99,7 +99,8 @@ class ProfilesController < Profiles::ApplicationController :username, :website_url, :organization, - :preferred_language + :preferred_language, + :private_profile ) end end diff --git a/app/controllers/projects/wikis_controller.rb b/app/controllers/projects/wikis_controller.rb index 9dc0c31be49..b7c656246ef 100644 --- a/app/controllers/projects/wikis_controller.rb +++ b/app/controllers/projects/wikis_controller.rb @@ -112,7 +112,7 @@ class Projects::WikisController < Projects::ApplicationController private def load_project_wiki - @project_wiki = ProjectWiki.new(@project, current_user) + @project_wiki = load_wiki # Call #wiki to make sure the Wiki Repo is initialized @project_wiki.wiki @@ -128,6 +128,10 @@ class Projects::WikisController < Projects::ApplicationController false end + def load_wiki + ProjectWiki.new(@project, current_user) + end + def wiki_params params.require(:wiki).permit(:title, :content, :format, :message, :last_commit_sha) end diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index 9dd652206fe..4ca42e2d4a2 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -157,6 +157,8 @@ class SessionsController < Devise::SessionsController end def auto_sign_in_with_provider + return unless Gitlab::Auth.omniauth_enabled? + provider = Gitlab.config.omniauth.auto_sign_in_with_provider return unless provider.present? diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 31f47a7aa7c..2f65f4a7403 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -13,6 +13,8 @@ class UsersController < ApplicationController skip_before_action :authenticate_user! before_action :user, except: [:exists] + before_action :authorize_read_user_profile!, + only: [:calendar, :calendar_activities, :groups, :projects, :contributed_projects, :snippets] def show respond_to do |format| @@ -148,4 +150,8 @@ class UsersController < ApplicationController def build_canonical_path(user) url_for(safe_params.merge(username: user.to_param)) end + + def authorize_read_user_profile! + access_denied! unless can?(current_user, :read_user_profile, user) + end end diff --git a/app/finders/groups_finder.rb b/app/finders/groups_finder.rb index 0754123a3cf..0eeba1d2428 100644 --- a/app/finders/groups_finder.rb +++ b/app/finders/groups_finder.rb @@ -8,6 +8,7 @@ # owned: boolean # parent: Group # all_available: boolean (defaults to true) +# min_access_level: integer # # Users with full private access can see all groups. The `owned` and `parent` # params can be used to restrict the groups that are returned. @@ -39,6 +40,7 @@ class GroupsFinder < UnionFinder def all_groups return [owned_groups] if params[:owned] + return [groups_with_min_access_level] if min_access_level? return [Group.all] if current_user&.full_private_access? && all_available? groups = [] @@ -56,6 +58,16 @@ class GroupsFinder < UnionFinder current_user.groups end + def groups_with_min_access_level + groups = current_user + .groups + .where('members.access_level >= ?', params[:min_access_level]) + + Gitlab::GroupHierarchy + .new(groups) + .base_and_descendants + end + def by_parent(groups) return groups unless params[:parent] @@ -73,4 +85,8 @@ class GroupsFinder < UnionFinder def all_available? params.fetch(:all_available, true) end + + def min_access_level? + current_user && params[:min_access_level].present? + end end diff --git a/app/finders/personal_projects_finder.rb b/app/finders/personal_projects_finder.rb index 5aea0cb8192..a56a3a1e1a9 100644 --- a/app/finders/personal_projects_finder.rb +++ b/app/finders/personal_projects_finder.rb @@ -1,6 +1,9 @@ class PersonalProjectsFinder < UnionFinder - def initialize(user) + include Gitlab::Allowable + + def initialize(user, params = {}) @user = user + @params = params end # Finds the projects belonging to the user in "@user", limited to either @@ -8,9 +11,13 @@ class PersonalProjectsFinder < UnionFinder # # current_user - When given the list of projects is limited to those only # visible by this user. + # params - Optional query parameters + # min_access_level: integer # # Returns an ActiveRecord::Relation. def execute(current_user = nil) + return Project.none unless can?(current_user, :read_user_profile, @user) + segments = all_projects(current_user) find_union(segments, Project).includes(:namespace).order_updated_desc @@ -19,11 +26,21 @@ class PersonalProjectsFinder < UnionFinder private def all_projects(current_user) - projects = [] + return [projects_with_min_access_level(current_user)] if current_user && min_access_level? + projects = [] projects << @user.personal_projects.visible_to_user(current_user) if current_user projects << @user.personal_projects.public_to_user(current_user) - projects end + + def projects_with_min_access_level(current_user) + @user + .personal_projects + .visible_to_user_and_access_level(current_user, @params[:min_access_level]) + end + + def min_access_level? + @params[:min_access_level].present? + end end diff --git a/app/finders/projects_finder.rb b/app/finders/projects_finder.rb index b06595081e7..cac6643eff3 100644 --- a/app/finders/projects_finder.rb +++ b/app/finders/projects_finder.rb @@ -17,6 +17,7 @@ # search: string # non_archived: boolean # archived: 'only' or boolean +# min_access_level: integer # class ProjectsFinder < UnionFinder include CustomAttributesFilter @@ -34,7 +35,7 @@ class ProjectsFinder < UnionFinder user = params.delete(:user) collection = if user - PersonalProjectsFinder.new(user).execute(current_user) + PersonalProjectsFinder.new(user, finder_params).execute(current_user) else init_collection end @@ -65,6 +66,8 @@ class ProjectsFinder < UnionFinder def collection_with_user if owned_projects? current_user.owned_projects + elsif min_access_level? + current_user.authorized_projects.where('project_authorizations.access_level >= ?', params[:min_access_level]) else if private_only? current_user.authorized_projects @@ -76,7 +79,7 @@ class ProjectsFinder < UnionFinder # Builds a collection for an anonymous user. def collection_without_user - if private_only? || owned_projects? + if private_only? || owned_projects? || min_access_level? Project.none else Project.public_to_user @@ -91,6 +94,10 @@ class ProjectsFinder < UnionFinder params[:non_public].present? end + def min_access_level? + params[:min_access_level].present? + end + def by_ids(items) project_ids_relation ? items.where(id: project_ids_relation) : items end @@ -143,4 +150,10 @@ class ProjectsFinder < UnionFinder projects end end + + def finder_params + return {} unless min_access_level? + + { min_access_level: params[:min_access_level] } + end end diff --git a/app/finders/user_recent_events_finder.rb b/app/finders/user_recent_events_finder.rb index 74776b2ed1f..876f086a3ef 100644 --- a/app/finders/user_recent_events_finder.rb +++ b/app/finders/user_recent_events_finder.rb @@ -7,6 +7,7 @@ class UserRecentEventsFinder prepend FinderWithCrossProjectAccess include FinderMethods + include Gitlab::Allowable requires_cross_project_access @@ -21,6 +22,8 @@ class UserRecentEventsFinder end def execute + return Event.none unless can?(current_user, :read_user_profile, target_user) + recent_events(params[:offset] || 0) .joins(:project) .with_associations diff --git a/app/helpers/auth_helper.rb b/app/helpers/auth_helper.rb index d2daee22aba..18f0979fc86 100644 --- a/app/helpers/auth_helper.rb +++ b/app/helpers/auth_helper.rb @@ -7,7 +7,7 @@ module AuthHelper end def omniauth_enabled? - Gitlab.config.omniauth.enabled + Gitlab::Auth.omniauth_enabled? end def provider_has_icon?(name) diff --git a/app/helpers/button_helper.rb b/app/helpers/button_helper.rb index 3605d6a3c95..0171a880164 100644 --- a/app/helpers/button_helper.rb +++ b/app/helpers/button_helper.rb @@ -51,7 +51,7 @@ module ButtonHelper } content_tag :button, button_attributes do - concat(icon('clipboard', 'aria-hidden': 'true')) unless hide_button_icon + concat(sprite_icon('duplicate')) unless hide_button_icon concat(button_text) end end diff --git a/app/helpers/ci_status_helper.rb b/app/helpers/ci_status_helper.rb index f49b5c7b51a..330959e536d 100644 --- a/app/helpers/ci_status_helper.rb +++ b/app/helpers/ci_status_helper.rb @@ -56,7 +56,7 @@ module CiStatusHelper status.humanize end - def ci_icon_for_status(status) + def ci_icon_for_status(status, size: 16) if detailed_status?(status) return sprite_icon(status.icon) end @@ -85,7 +85,7 @@ module CiStatusHelper 'status_canceled' end - sprite_icon(icon_name, size: 16) + sprite_icon(icon_name, size: size) end def pipeline_status_cache_key(pipeline_status) @@ -111,7 +111,8 @@ module CiStatusHelper 'commit', commit.status(ref), path, - tooltip_placement: tooltip_placement) + tooltip_placement: tooltip_placement, + icon_size: 24) end def render_pipeline_status(pipeline, tooltip_placement: 'left') @@ -125,16 +126,16 @@ module CiStatusHelper Ci::Runner.instance_type.blank? end - def render_status_with_link(type, status, path = nil, tooltip_placement: 'left', cssclass: '', container: 'body') + def render_status_with_link(type, status, path = nil, tooltip_placement: 'left', cssclass: '', container: 'body', icon_size: 16) klass = "ci-status-link ci-status-icon-#{status.dasherize} #{cssclass}" title = "#{type.titleize}: #{ci_label_for_status(status)}" data = { toggle: 'tooltip', placement: tooltip_placement, container: container } if path - link_to ci_icon_for_status(status), path, + link_to ci_icon_for_status(status, size: icon_size), path, class: klass, title: title, data: data else - content_tag :span, ci_icon_for_status(status), + content_tag :span, ci_icon_for_status(status, size: icon_size), class: klass, title: title, data: data end end diff --git a/app/helpers/commits_helper.rb b/app/helpers/commits_helper.rb index e5c3be47801..89fe90fd801 100644 --- a/app/helpers/commits_helper.rb +++ b/app/helpers/commits_helper.rb @@ -145,15 +145,14 @@ module CommitsHelper person_name end - options = { - class: "commit-#{options[:source]}-link has-tooltip", - title: source_email + link_options = { + class: "commit-#{options[:source]}-link" } if user.nil? - mail_to(source_email, text, options) + mail_to(source_email, text, link_options) else - link_to(text, user_path(user), options) + link_to(text, user_path(user), link_options) end end diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index 221f1aa9dd8..aaf9dff43ee 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -63,10 +63,10 @@ module ProjectsHelper author_html = author_html.html_safe if opts[:name] - link_to(author_html, user_path(author), class: "author_link #{"#{opts[:extra_class]}" if opts[:extra_class]} #{"#{opts[:mobile_classes]}" if opts[:mobile_classes]}").html_safe + link_to(author_html, user_path(author), class: "author-link #{"#{opts[:extra_class]}" if opts[:extra_class]} #{"#{opts[:mobile_classes]}" if opts[:mobile_classes]}").html_safe else title = opts[:title].sub(":name", sanitize(author.name)) - link_to(author_html, user_path(author), class: "author_link has-tooltip", title: title, data: { container: 'body' }).html_safe + link_to(author_html, user_path(author), class: "author-link has-tooltip", title: title, data: { container: 'body' }).html_safe end end diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb index 4d17b22a4a1..8ee4203b6f5 100644 --- a/app/helpers/users_helper.rb +++ b/app/helpers/users_helper.rb @@ -42,7 +42,13 @@ module UsersHelper private def get_profile_tabs - [:activity, :groups, :contributed, :projects, :snippets] + tabs = [] + + if can?(current_user, :read_user_profile, @user) + tabs += [:activity, :groups, :contributed, :projects, :snippets] + end + + tabs end def get_current_user_menu_items diff --git a/app/helpers/visibility_level_helper.rb b/app/helpers/visibility_level_helper.rb index e395cda03d3..cf2fe5a2019 100644 --- a/app/helpers/visibility_level_helper.rb +++ b/app/helpers/visibility_level_helper.rb @@ -126,10 +126,9 @@ module VisibilityLevelHelper end def visibility_icon_description(form_model) - case form_model - when Project + if form_model.respond_to?(:visibility_level_allowed_as_fork?) project_visibility_icon_description(form_model.visibility_level) - when Group + elsif form_model.respond_to?(:visibility_level_allowed_by_sub_groups?) group_visibility_icon_description(form_model.visibility_level) end end diff --git a/app/models/deploy_token.rb b/app/models/deploy_token.rb index 5082dc45368..7ab647abe93 100644 --- a/app/models/deploy_token.rb +++ b/app/models/deploy_token.rb @@ -27,7 +27,7 @@ class DeployToken < ActiveRecord::Base end def active? - !revoked + !revoked && expires_at > Date.today end def scopes @@ -58,6 +58,10 @@ class DeployToken < ActiveRecord::Base write_attribute(:expires_at, value.presence || Forever.date) end + def admin? + false + end + private def ensure_at_least_one_scope diff --git a/app/models/project.rb b/app/models/project.rb index 5f582dfa5ee..325dbd0197f 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -154,6 +154,7 @@ class Project < ActiveRecord::Base has_one :mock_monitoring_service has_one :microsoft_teams_service has_one :packagist_service + has_one :hangouts_chat_service # TODO: replace these relations with the fork network versions has_one :forked_project_link, foreign_key: "forked_to_project_id" @@ -326,6 +327,7 @@ class Project < ActiveRecord::Base scope :joined, ->(user) { where('namespace_id != ?', user.namespace_id) } scope :starred_by, ->(user) { joins(:users_star_projects).where('users_star_projects.user_id': user.id) } scope :visible_to_user, ->(user) { where(id: user.authorized_projects.select(:id).reorder(nil)) } + scope :visible_to_user_and_access_level, ->(user, access_level) { where(id: user.authorized_projects.where('project_authorizations.access_level >= ?', access_level).select(:id).reorder(nil)) } scope :archived, -> { where(archived: true) } scope :non_archived, -> { where(archived: false) } scope :for_milestones, ->(ids) { joins(:milestones).where('milestones.id' => ids).distinct } diff --git a/app/models/project_services/hangouts_chat_service.rb b/app/models/project_services/hangouts_chat_service.rb new file mode 100644 index 00000000000..a8512c5f57c --- /dev/null +++ b/app/models/project_services/hangouts_chat_service.rb @@ -0,0 +1,67 @@ +require 'hangouts_chat' + +class HangoutsChatService < ChatNotificationService + def title + 'Hangouts Chat' + end + + def description + 'Receive event notifications in Google Hangouts Chat' + end + + def self.to_param + 'hangouts_chat' + end + + def help + 'This service sends notifications about projects events to Google Hangouts Chat room.<br /> + To set up this service: + <ol> + <li><a href="https://developers.google.com/hangouts/chat/how-tos/webhooks">Set up an incoming webhook for your room</a>. All notifications will come to this room.</li> + <li>Paste the <strong>Webhook URL</strong> into the field below.</li> + <li>Select events below to enable notifications.</li> + </ol>' + end + + def event_field(event) + end + + def default_channel_placeholder + end + + def webhook_placeholder + 'https://chat.googleapis.com/v1/spaces…' + end + + def default_fields + [ + { type: 'text', name: 'webhook', placeholder: "e.g. #{webhook_placeholder}" }, + { type: 'checkbox', name: 'notify_only_broken_pipelines' }, + { type: 'checkbox', name: 'notify_only_default_branch' } + ] + end + + private + + def notify(message, opts) + simple_text = parse_simple_text_message(message) + HangoutsChat::Sender.new(webhook).simple(simple_text) + end + + def parse_simple_text_message(message) + header = message.pretext + return header if message.attachments.empty? + + attachment = message.attachments.first + title = format_attachment_title(attachment) + body = attachment[:text] + + [header, title, body].compact.join("\n") + end + + def format_attachment_title(attachment) + return attachment[:title] unless attachment[:title_link] + + "<#{attachment[:title_link]}|#{attachment[:title]}>" + end +end diff --git a/app/models/project_wiki.rb b/app/models/project_wiki.rb index 3aa56b3983f..f4b3421f04b 100644 --- a/app/models/project_wiki.rb +++ b/app/models/project_wiki.rb @@ -82,7 +82,7 @@ class ProjectWiki # Returns an Array of Gitlab WikiPage instances or an # empty Array if this Wiki has no pages. - def pages(limit: nil) + def pages(limit: 0) wiki.pages(limit: limit).map { |page| WikiPage.new(self, page, true) } end diff --git a/app/models/service.rb b/app/models/service.rb index ad835293b46..cbfe0c6eedd 100644 --- a/app/models/service.rb +++ b/app/models/service.rb @@ -254,6 +254,7 @@ class Service < ActiveRecord::Base emails_on_push external_wiki flowdock + hangouts_chat hipchat irker jira diff --git a/app/policies/application_setting/term_policy.rb b/app/policies/application_setting/term_policy.rb index f03bf748c76..17f00f33d35 100644 --- a/app/policies/application_setting/term_policy.rb +++ b/app/policies/application_setting/term_policy.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class ApplicationSetting class TermPolicy < BasePolicy include Gitlab::Utils::StrongMemoize diff --git a/app/policies/base_policy.rb b/app/policies/base_policy.rb index 603218aa6df..0d0f1c28bad 100644 --- a/app/policies/base_policy.rb +++ b/app/policies/base_policy.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require_dependency 'declarative_policy' class BasePolicy < DeclarativePolicy::Base diff --git a/app/policies/ci/build_policy.rb b/app/policies/ci/build_policy.rb index 75c7e529902..3858b29c82c 100644 --- a/app/policies/ci/build_policy.rb +++ b/app/policies/ci/build_policy.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Ci class BuildPolicy < CommitStatusPolicy condition(:protected_ref) do diff --git a/app/policies/ci/pipeline_policy.rb b/app/policies/ci/pipeline_policy.rb index b81329d0625..f9623587957 100644 --- a/app/policies/ci/pipeline_policy.rb +++ b/app/policies/ci/pipeline_policy.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Ci class PipelinePolicy < BasePolicy delegate { @subject.project } diff --git a/app/policies/ci/pipeline_schedule_policy.rb b/app/policies/ci/pipeline_schedule_policy.rb index ecba0488d3c..cf3f784f851 100644 --- a/app/policies/ci/pipeline_schedule_policy.rb +++ b/app/policies/ci/pipeline_schedule_policy.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Ci class PipelineSchedulePolicy < PipelinePolicy alias_method :pipeline_schedule, :subject diff --git a/app/policies/ci/runner_policy.rb b/app/policies/ci/runner_policy.rb index 895abe87d86..c44f22b6ad3 100644 --- a/app/policies/ci/runner_policy.rb +++ b/app/policies/ci/runner_policy.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Ci class RunnerPolicy < BasePolicy with_options scope: :subject, score: 0 diff --git a/app/policies/ci/trigger_policy.rb b/app/policies/ci/trigger_policy.rb index 5592ac30812..209db44539c 100644 --- a/app/policies/ci/trigger_policy.rb +++ b/app/policies/ci/trigger_policy.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Ci class TriggerPolicy < BasePolicy delegate { @subject.project } diff --git a/app/policies/clusters/cluster_policy.rb b/app/policies/clusters/cluster_policy.rb index b5b24491655..147943a3d6c 100644 --- a/app/policies/clusters/cluster_policy.rb +++ b/app/policies/clusters/cluster_policy.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Clusters class ClusterPolicy < BasePolicy alias_method :cluster, :subject diff --git a/app/policies/commit_status_policy.rb b/app/policies/commit_status_policy.rb index 24b2a4cc7fd..eea2a24fb2d 100644 --- a/app/policies/commit_status_policy.rb +++ b/app/policies/commit_status_policy.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CommitStatusPolicy < BasePolicy delegate { @subject.project } diff --git a/app/policies/deploy_key_policy.rb b/app/policies/deploy_key_policy.rb index 62a22a59be6..204c54a5b20 100644 --- a/app/policies/deploy_key_policy.rb +++ b/app/policies/deploy_key_policy.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class DeployKeyPolicy < BasePolicy with_options scope: :subject, score: 0 condition(:private_deploy_key) { @subject.private? } diff --git a/app/policies/deploy_token_policy.rb b/app/policies/deploy_token_policy.rb index d1b459cfc90..e648df3edfc 100644 --- a/app/policies/deploy_token_policy.rb +++ b/app/policies/deploy_token_policy.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class DeployTokenPolicy < BasePolicy with_options scope: :subject, score: 0 condition(:maintainer) { @subject.project.team.maintainer?(@user) } diff --git a/app/policies/deployment_policy.rb b/app/policies/deployment_policy.rb index 62b63b9f87b..56ac898b6ab 100644 --- a/app/policies/deployment_policy.rb +++ b/app/policies/deployment_policy.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class DeploymentPolicy < BasePolicy delegate { @subject.project } end diff --git a/app/policies/environment_policy.rb b/app/policies/environment_policy.rb index 2d07311db72..d1243491f5a 100644 --- a/app/policies/environment_policy.rb +++ b/app/policies/environment_policy.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class EnvironmentPolicy < BasePolicy delegate { @subject.project } diff --git a/app/policies/external_issue_policy.rb b/app/policies/external_issue_policy.rb index e031b38078c..1106536e075 100644 --- a/app/policies/external_issue_policy.rb +++ b/app/policies/external_issue_policy.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class ExternalIssuePolicy < BasePolicy delegate { @subject.project } end diff --git a/app/policies/global_policy.rb b/app/policies/global_policy.rb index 1cf5515d9d7..6e3827736b2 100644 --- a/app/policies/global_policy.rb +++ b/app/policies/global_policy.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class GlobalPolicy < BasePolicy desc "User is blocked" with_options scope: :user, score: 0 diff --git a/app/policies/group_label_policy.rb b/app/policies/group_label_policy.rb index e3dd3296699..9f3acd44b23 100644 --- a/app/policies/group_label_policy.rb +++ b/app/policies/group_label_policy.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class GroupLabelPolicy < BasePolicy delegate { @subject.group } end diff --git a/app/policies/group_member_policy.rb b/app/policies/group_member_policy.rb index 23dd0d7cd23..6f1afb87c85 100644 --- a/app/policies/group_member_policy.rb +++ b/app/policies/group_member_policy.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class GroupMemberPolicy < BasePolicy delegate :group diff --git a/app/policies/group_policy.rb b/app/policies/group_policy.rb index dc339b71ec7..a8d7a05f509 100644 --- a/app/policies/group_policy.rb +++ b/app/policies/group_policy.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class GroupPolicy < BasePolicy desc "Group is public" with_options scope: :subject, score: 0 diff --git a/app/policies/issuable_policy.rb b/app/policies/issuable_policy.rb index b431d376e3d..198bb168d85 100644 --- a/app/policies/issuable_policy.rb +++ b/app/policies/issuable_policy.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class IssuablePolicy < BasePolicy delegate { @subject.project } diff --git a/app/policies/issue_policy.rb b/app/policies/issue_policy.rb index 263c6e3039c..94b5f37c682 100644 --- a/app/policies/issue_policy.rb +++ b/app/policies/issue_policy.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class IssuePolicy < IssuablePolicy # This class duplicates the same check of Issue#readable_by? for performance reasons # Make sure to sync this class checks with issue.rb to avoid security problems. diff --git a/app/policies/merge_request_policy.rb b/app/policies/merge_request_policy.rb index c3fe857f8a2..a2950951d03 100644 --- a/app/policies/merge_request_policy.rb +++ b/app/policies/merge_request_policy.rb @@ -1,2 +1,4 @@ +# frozen_string_literal: true + class MergeRequestPolicy < IssuablePolicy end diff --git a/app/policies/namespace_policy.rb b/app/policies/namespace_policy.rb index eb01218eb0a..2babcb0a2d9 100644 --- a/app/policies/namespace_policy.rb +++ b/app/policies/namespace_policy.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class NamespacePolicy < BasePolicy rule { anonymous }.prevent_all diff --git a/app/policies/nil_policy.rb b/app/policies/nil_policy.rb index 13f46ba60f0..fc969f8cd05 100644 --- a/app/policies/nil_policy.rb +++ b/app/policies/nil_policy.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class NilPolicy < BasePolicy rule { default }.prevent_all end diff --git a/app/policies/note_policy.rb b/app/policies/note_policy.rb index 077a6761ee6..bbc2b48b856 100644 --- a/app/policies/note_policy.rb +++ b/app/policies/note_policy.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class NotePolicy < BasePolicy delegate { @subject.project } delegate { @subject.noteable if DeclarativePolicy.has_policy?(@subject.noteable) } diff --git a/app/policies/personal_snippet_policy.rb b/app/policies/personal_snippet_policy.rb index c1a84727cfa..777f933cdcd 100644 --- a/app/policies/personal_snippet_policy.rb +++ b/app/policies/personal_snippet_policy.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class PersonalSnippetPolicy < BasePolicy condition(:public_snippet, scope: :subject) { @subject.public? } condition(:is_author) { @user && @subject.author == @user } diff --git a/app/policies/project_label_policy.rb b/app/policies/project_label_policy.rb index 2d0f021118b..5ce896ecaf2 100644 --- a/app/policies/project_label_policy.rb +++ b/app/policies/project_label_policy.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class ProjectLabelPolicy < BasePolicy delegate { @subject.project } end diff --git a/app/policies/project_member_policy.rb b/app/policies/project_member_policy.rb index 9aedb620be9..f2f18406bd3 100644 --- a/app/policies/project_member_policy.rb +++ b/app/policies/project_member_policy.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class ProjectMemberPolicy < BasePolicy delegate { @subject.project } diff --git a/app/policies/project_policy.rb b/app/policies/project_policy.rb index bc49092633f..f52a3bad77d 100644 --- a/app/policies/project_policy.rb +++ b/app/policies/project_policy.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class ProjectPolicy < BasePolicy extend ClassMethods diff --git a/app/policies/project_policy/class_methods.rb b/app/policies/project_policy/class_methods.rb index 60e5aba00ba..42d993406a9 100644 --- a/app/policies/project_policy/class_methods.rb +++ b/app/policies/project_policy/class_methods.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class ProjectPolicy module ClassMethods def create_read_update_admin_destroy(name) diff --git a/app/policies/project_snippet_policy.rb b/app/policies/project_snippet_policy.rb index dd270643bbf..288bf070cfc 100644 --- a/app/policies/project_snippet_policy.rb +++ b/app/policies/project_snippet_policy.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class ProjectSnippetPolicy < BasePolicy delegate :project diff --git a/app/policies/protected_branch_policy.rb b/app/policies/protected_branch_policy.rb index 1a7faa4db40..0e83d2e5834 100644 --- a/app/policies/protected_branch_policy.rb +++ b/app/policies/protected_branch_policy.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class ProtectedBranchPolicy < BasePolicy delegate { @subject.project } diff --git a/app/policies/user_policy.rb b/app/policies/user_policy.rb index ee219f0a0d0..b5717029354 100644 --- a/app/policies/user_policy.rb +++ b/app/policies/user_policy.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class UserPolicy < BasePolicy desc "The current user is the user in question" condition(:user_is_self, score: 0) { @subject == @user } @@ -5,6 +7,9 @@ class UserPolicy < BasePolicy desc "This is the ghost user" condition(:subject_ghost, scope: :subject, score: 0) { @subject.ghost? } + desc "The profile is private" + condition(:private_profile, scope: :subject, score: 0) { @subject.private_profile? } + rule { ~restricted_public_level }.enable :read_user rule { ~anonymous }.enable :read_user @@ -12,4 +17,7 @@ class UserPolicy < BasePolicy enable :destroy_user enable :update_user end + + rule { default }.enable :read_user_profile + rule { private_profile & ~(user_is_self | admin) }.prevent :read_user_profile end diff --git a/app/presenters/ci/build_metadata_presenter.rb b/app/presenters/ci/build_metadata_presenter.rb index 5048f967ea8..015b1f67db7 100644 --- a/app/presenters/ci/build_metadata_presenter.rb +++ b/app/presenters/ci/build_metadata_presenter.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Ci class BuildMetadataPresenter < Gitlab::View::Presenter::Delegated TIMEOUT_SOURCES = { diff --git a/app/presenters/ci/build_presenter.rb b/app/presenters/ci/build_presenter.rb index e0aaa5cb736..5331cdf632b 100644 --- a/app/presenters/ci/build_presenter.rb +++ b/app/presenters/ci/build_presenter.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Ci class BuildPresenter < CommitStatusPresenter def erased_by_user? diff --git a/app/presenters/ci/group_variable_presenter.rb b/app/presenters/ci/group_variable_presenter.rb index 98d68bc7a83..99011150c84 100644 --- a/app/presenters/ci/group_variable_presenter.rb +++ b/app/presenters/ci/group_variable_presenter.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Ci class GroupVariablePresenter < Gitlab::View::Presenter::Delegated presents :variable diff --git a/app/presenters/ci/pipeline_presenter.rb b/app/presenters/ci/pipeline_presenter.rb index cc2bce9862d..93a38f92073 100644 --- a/app/presenters/ci/pipeline_presenter.rb +++ b/app/presenters/ci/pipeline_presenter.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Ci class PipelinePresenter < Gitlab::View::Presenter::Delegated include Gitlab::Utils::StrongMemoize diff --git a/app/presenters/ci/variable_presenter.rb b/app/presenters/ci/variable_presenter.rb index 96159f88c59..f027f3aa560 100644 --- a/app/presenters/ci/variable_presenter.rb +++ b/app/presenters/ci/variable_presenter.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Ci class VariablePresenter < Gitlab::View::Presenter::Delegated presents :variable diff --git a/app/presenters/clusters/cluster_presenter.rb b/app/presenters/clusters/cluster_presenter.rb index a424da5ab24..dfdd8e82f97 100644 --- a/app/presenters/clusters/cluster_presenter.rb +++ b/app/presenters/clusters/cluster_presenter.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Clusters class ClusterPresenter < Gitlab::View::Presenter::Delegated presents :cluster diff --git a/app/presenters/commit_status_presenter.rb b/app/presenters/commit_status_presenter.rb index 9a7aaf4ef32..3a9088cfcb8 100644 --- a/app/presenters/commit_status_presenter.rb +++ b/app/presenters/commit_status_presenter.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CommitStatusPresenter < Gitlab::View::Presenter::Delegated CALLOUT_FAILURE_MESSAGES = { unknown_failure: 'There is an unknown failure, please try again', diff --git a/app/presenters/conversational_development_index/metric_presenter.rb b/app/presenters/conversational_development_index/metric_presenter.rb index bb65ba2646b..e0312c6f431 100644 --- a/app/presenters/conversational_development_index/metric_presenter.rb +++ b/app/presenters/conversational_development_index/metric_presenter.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module ConversationalDevelopmentIndex class MetricPresenter < Gitlab::View::Presenter::Simple def cards diff --git a/app/presenters/generic_commit_status_presenter.rb b/app/presenters/generic_commit_status_presenter.rb index da09df29a37..a1dc72d5b98 100644 --- a/app/presenters/generic_commit_status_presenter.rb +++ b/app/presenters/generic_commit_status_presenter.rb @@ -1,2 +1,4 @@ +# frozen_string_literal: true + class GenericCommitStatusPresenter < CommitStatusPresenter end diff --git a/app/presenters/group_member_presenter.rb b/app/presenters/group_member_presenter.rb index 8f53dfa105e..c4dcc9e60f9 100644 --- a/app/presenters/group_member_presenter.rb +++ b/app/presenters/group_member_presenter.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class GroupMemberPresenter < MemberPresenter private diff --git a/app/presenters/member_presenter.rb b/app/presenters/member_presenter.rb index 7d2f9303b8f..2497bea4aff 100644 --- a/app/presenters/member_presenter.rb +++ b/app/presenters/member_presenter.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class MemberPresenter < Gitlab::View::Presenter::Delegated presents :member diff --git a/app/presenters/members_presenter.rb b/app/presenters/members_presenter.rb index e4aba37b69e..03ebea36d49 100644 --- a/app/presenters/members_presenter.rb +++ b/app/presenters/members_presenter.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class MembersPresenter < Gitlab::View::Presenter::Delegated include Enumerable diff --git a/app/presenters/merge_request_presenter.rb b/app/presenters/merge_request_presenter.rb index f77b3541644..ffa238a63d5 100644 --- a/app/presenters/merge_request_presenter.rb +++ b/app/presenters/merge_request_presenter.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class MergeRequestPresenter < Gitlab::View::Presenter::Delegated include ActionView::Helpers::UrlHelper include GitlabRoutingHelper diff --git a/app/presenters/project_member_presenter.rb b/app/presenters/project_member_presenter.rb index 7f42d2b70df..e4731074e86 100644 --- a/app/presenters/project_member_presenter.rb +++ b/app/presenters/project_member_presenter.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class ProjectMemberPresenter < MemberPresenter private diff --git a/app/presenters/project_presenter.rb b/app/presenters/project_presenter.rb index d4d622d84ab..4c2f33213d6 100644 --- a/app/presenters/project_presenter.rb +++ b/app/presenters/project_presenter.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class ProjectPresenter < Gitlab::View::Presenter::Delegated include ActionView::Helpers::NumberHelper include ActionView::Helpers::UrlHelper diff --git a/app/presenters/projects/settings/deploy_keys_presenter.rb b/app/presenters/projects/settings/deploy_keys_presenter.rb index c226586fba5..28eaef00a12 100644 --- a/app/presenters/projects/settings/deploy_keys_presenter.rb +++ b/app/presenters/projects/settings/deploy_keys_presenter.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Projects module Settings class DeployKeysPresenter < Gitlab::View::Presenter::Simple diff --git a/app/serializers/analytics_build_entity.rb b/app/serializers/analytics_build_entity.rb index bdc22d71202..99663c8d5eb 100644 --- a/app/serializers/analytics_build_entity.rb +++ b/app/serializers/analytics_build_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AnalyticsBuildEntity < Grape::Entity include RequestAwareEntity include EntityDateHelper diff --git a/app/serializers/analytics_build_serializer.rb b/app/serializers/analytics_build_serializer.rb index f172d67d356..9c9f76a1c28 100644 --- a/app/serializers/analytics_build_serializer.rb +++ b/app/serializers/analytics_build_serializer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AnalyticsBuildSerializer < BaseSerializer entity AnalyticsBuildEntity end diff --git a/app/serializers/analytics_commit_entity.rb b/app/serializers/analytics_commit_entity.rb index 402cecbfd08..b25c603c9f0 100644 --- a/app/serializers/analytics_commit_entity.rb +++ b/app/serializers/analytics_commit_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AnalyticsCommitEntity < CommitEntity include EntityDateHelper diff --git a/app/serializers/analytics_commit_serializer.rb b/app/serializers/analytics_commit_serializer.rb index cdbfecf2b70..0f65687a3c0 100644 --- a/app/serializers/analytics_commit_serializer.rb +++ b/app/serializers/analytics_commit_serializer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AnalyticsCommitSerializer < BaseSerializer entity AnalyticsCommitEntity end diff --git a/app/serializers/analytics_generic_serializer.rb b/app/serializers/analytics_generic_serializer.rb index 9f4859e8410..10391c13034 100644 --- a/app/serializers/analytics_generic_serializer.rb +++ b/app/serializers/analytics_generic_serializer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AnalyticsGenericSerializer < BaseSerializer def represent(resource, opts = {}) resource.symbolize_keys! diff --git a/app/serializers/analytics_issue_entity.rb b/app/serializers/analytics_issue_entity.rb index b7d95ea020f..ab15bd0ac7a 100644 --- a/app/serializers/analytics_issue_entity.rb +++ b/app/serializers/analytics_issue_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AnalyticsIssueEntity < Grape::Entity include RequestAwareEntity include EntityDateHelper diff --git a/app/serializers/analytics_issue_serializer.rb b/app/serializers/analytics_issue_serializer.rb index 4fb3e8f1bb4..4a1777276a4 100644 --- a/app/serializers/analytics_issue_serializer.rb +++ b/app/serializers/analytics_issue_serializer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AnalyticsIssueSerializer < AnalyticsGenericSerializer entity AnalyticsIssueEntity end diff --git a/app/serializers/analytics_merge_request_entity.rb b/app/serializers/analytics_merge_request_entity.rb index 888265eaa38..b7134da9461 100644 --- a/app/serializers/analytics_merge_request_entity.rb +++ b/app/serializers/analytics_merge_request_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AnalyticsMergeRequestEntity < AnalyticsIssueEntity expose :state diff --git a/app/serializers/analytics_merge_request_serializer.rb b/app/serializers/analytics_merge_request_serializer.rb index 4622a1dd855..f0b9115d02c 100644 --- a/app/serializers/analytics_merge_request_serializer.rb +++ b/app/serializers/analytics_merge_request_serializer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AnalyticsMergeRequestSerializer < AnalyticsGenericSerializer entity AnalyticsMergeRequestEntity end diff --git a/app/serializers/analytics_stage_entity.rb b/app/serializers/analytics_stage_entity.rb index 3e355a13e06..ae7c20c3bba 100644 --- a/app/serializers/analytics_stage_entity.rb +++ b/app/serializers/analytics_stage_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AnalyticsStageEntity < Grape::Entity include EntityDateHelper diff --git a/app/serializers/analytics_stage_serializer.rb b/app/serializers/analytics_stage_serializer.rb index 613cf6874d8..86786273240 100644 --- a/app/serializers/analytics_stage_serializer.rb +++ b/app/serializers/analytics_stage_serializer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AnalyticsStageSerializer < BaseSerializer entity AnalyticsStageEntity end diff --git a/app/serializers/analytics_summary_entity.rb b/app/serializers/analytics_summary_entity.rb index 9c37afd53e1..39c6b4b06b2 100644 --- a/app/serializers/analytics_summary_entity.rb +++ b/app/serializers/analytics_summary_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AnalyticsSummaryEntity < Grape::Entity expose :value, safe: true expose :title diff --git a/app/serializers/analytics_summary_serializer.rb b/app/serializers/analytics_summary_serializer.rb index c87a24aa47c..b22bd737f03 100644 --- a/app/serializers/analytics_summary_serializer.rb +++ b/app/serializers/analytics_summary_serializer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AnalyticsSummarySerializer < BaseSerializer entity AnalyticsSummaryEntity end diff --git a/app/serializers/award_emoji_entity.rb b/app/serializers/award_emoji_entity.rb index 6e03cd02392..212931a2fa9 100644 --- a/app/serializers/award_emoji_entity.rb +++ b/app/serializers/award_emoji_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AwardEmojiEntity < Grape::Entity expose :name expose :user, using: API::Entities::UserSafe diff --git a/app/serializers/base_serializer.rb b/app/serializers/base_serializer.rb index 8cade280b0c..7b65bd22f54 100644 --- a/app/serializers/base_serializer.rb +++ b/app/serializers/base_serializer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class BaseSerializer attr_reader :params diff --git a/app/serializers/blob_entity.rb b/app/serializers/blob_entity.rb index b501fd5e964..3ac61481dea 100644 --- a/app/serializers/blob_entity.rb +++ b/app/serializers/blob_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class BlobEntity < Grape::Entity include RequestAwareEntity diff --git a/app/serializers/build_action_entity.rb b/app/serializers/build_action_entity.rb index f2d76a8ad81..f9da3f63911 100644 --- a/app/serializers/build_action_entity.rb +++ b/app/serializers/build_action_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class BuildActionEntity < Grape::Entity include RequestAwareEntity diff --git a/app/serializers/build_artifact_entity.rb b/app/serializers/build_artifact_entity.rb index 6e0e33bc09b..414f436e76e 100644 --- a/app/serializers/build_artifact_entity.rb +++ b/app/serializers/build_artifact_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class BuildArtifactEntity < Grape::Entity include RequestAwareEntity diff --git a/app/serializers/build_details_entity.rb b/app/serializers/build_details_entity.rb index 2de9624aed4..b887b99d31c 100644 --- a/app/serializers/build_details_entity.rb +++ b/app/serializers/build_details_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class BuildDetailsEntity < JobEntity expose :coverage, :erased_at, :duration expose :tag_list, as: :tags diff --git a/app/serializers/build_metadata_entity.rb b/app/serializers/build_metadata_entity.rb index f16f3badffa..6242ee8957d 100644 --- a/app/serializers/build_metadata_entity.rb +++ b/app/serializers/build_metadata_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class BuildMetadataEntity < Grape::Entity expose :timeout_human_readable expose :timeout_source do |metadata| diff --git a/app/serializers/build_serializer.rb b/app/serializers/build_serializer.rb index bae9932847f..0649fdad6a8 100644 --- a/app/serializers/build_serializer.rb +++ b/app/serializers/build_serializer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class BuildSerializer < BaseSerializer entity JobEntity diff --git a/app/serializers/cluster_application_entity.rb b/app/serializers/cluster_application_entity.rb index 77fc3336521..2bd17e58086 100644 --- a/app/serializers/cluster_application_entity.rb +++ b/app/serializers/cluster_application_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class ClusterApplicationEntity < Grape::Entity expose :name expose :status_name, as: :status diff --git a/app/serializers/cluster_entity.rb b/app/serializers/cluster_entity.rb index 7e5b0997878..c59f68bbc49 100644 --- a/app/serializers/cluster_entity.rb +++ b/app/serializers/cluster_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class ClusterEntity < Grape::Entity include RequestAwareEntity diff --git a/app/serializers/cluster_serializer.rb b/app/serializers/cluster_serializer.rb index 2e13c1501e7..4bb4d4880d4 100644 --- a/app/serializers/cluster_serializer.rb +++ b/app/serializers/cluster_serializer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class ClusterSerializer < BaseSerializer entity ClusterEntity diff --git a/app/serializers/cohort_activity_month_entity.rb b/app/serializers/cohort_activity_month_entity.rb index e6788a8b596..cdbc89a2dcd 100644 --- a/app/serializers/cohort_activity_month_entity.rb +++ b/app/serializers/cohort_activity_month_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CohortActivityMonthEntity < Grape::Entity include ActionView::Helpers::NumberHelper diff --git a/app/serializers/cohort_entity.rb b/app/serializers/cohort_entity.rb index 7cdba5b0484..3d0213e1038 100644 --- a/app/serializers/cohort_entity.rb +++ b/app/serializers/cohort_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CohortEntity < Grape::Entity include ActionView::Helpers::NumberHelper diff --git a/app/serializers/cohorts_entity.rb b/app/serializers/cohorts_entity.rb index 98f5995ba6f..a84d568bf30 100644 --- a/app/serializers/cohorts_entity.rb +++ b/app/serializers/cohorts_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CohortsEntity < Grape::Entity expose :months_included expose :cohorts, using: CohortEntity diff --git a/app/serializers/cohorts_serializer.rb b/app/serializers/cohorts_serializer.rb index fe9367b13d8..ceca5e1e5a8 100644 --- a/app/serializers/cohorts_serializer.rb +++ b/app/serializers/cohorts_serializer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CohortsSerializer < AnalyticsGenericSerializer entity CohortsEntity end diff --git a/app/serializers/commit_entity.rb b/app/serializers/commit_entity.rb index c8dd98cc04d..b3287c66554 100644 --- a/app/serializers/commit_entity.rb +++ b/app/serializers/commit_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CommitEntity < API::Entities::Commit include RequestAwareEntity diff --git a/app/serializers/concerns/with_pagination.rb b/app/serializers/concerns/with_pagination.rb index 89631b73fcf..c8ffae355e8 100644 --- a/app/serializers/concerns/with_pagination.rb +++ b/app/serializers/concerns/with_pagination.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module WithPagination attr_accessor :paginator diff --git a/app/serializers/container_repositories_serializer.rb b/app/serializers/container_repositories_serializer.rb index 56dc70b5687..e1ce3c7b3ae 100644 --- a/app/serializers/container_repositories_serializer.rb +++ b/app/serializers/container_repositories_serializer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class ContainerRepositoriesSerializer < BaseSerializer entity ContainerRepositoryEntity end diff --git a/app/serializers/container_repository_entity.rb b/app/serializers/container_repository_entity.rb index 1103cf30a07..59bf35f5aff 100644 --- a/app/serializers/container_repository_entity.rb +++ b/app/serializers/container_repository_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class ContainerRepositoryEntity < Grape::Entity include RequestAwareEntity diff --git a/app/serializers/container_tag_entity.rb b/app/serializers/container_tag_entity.rb index 8f1488e6cbb..637294877f8 100644 --- a/app/serializers/container_tag_entity.rb +++ b/app/serializers/container_tag_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class ContainerTagEntity < Grape::Entity include RequestAwareEntity diff --git a/app/serializers/container_tags_serializer.rb b/app/serializers/container_tags_serializer.rb index 6ff3adff135..982ce33f6e3 100644 --- a/app/serializers/container_tags_serializer.rb +++ b/app/serializers/container_tags_serializer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class ContainerTagsSerializer < BaseSerializer entity ContainerTagEntity diff --git a/app/serializers/deploy_key_entity.rb b/app/serializers/deploy_key_entity.rb index 2678f99510c..54bf030aba1 100644 --- a/app/serializers/deploy_key_entity.rb +++ b/app/serializers/deploy_key_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class DeployKeyEntity < Grape::Entity expose :id expose :user_id diff --git a/app/serializers/deploy_key_serializer.rb b/app/serializers/deploy_key_serializer.rb index 8f849eb88b7..a1cd98b631b 100644 --- a/app/serializers/deploy_key_serializer.rb +++ b/app/serializers/deploy_key_serializer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class DeployKeySerializer < BaseSerializer entity DeployKeyEntity end diff --git a/app/serializers/deploy_keys_project_entity.rb b/app/serializers/deploy_keys_project_entity.rb index 568ef5ab75e..5775ad72d0d 100644 --- a/app/serializers/deploy_keys_project_entity.rb +++ b/app/serializers/deploy_keys_project_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class DeployKeysProjectEntity < Grape::Entity expose :can_push expose :project, using: ProjectEntity diff --git a/app/serializers/deployment_entity.rb b/app/serializers/deployment_entity.rb index 241c689bccd..344148a1fb7 100644 --- a/app/serializers/deployment_entity.rb +++ b/app/serializers/deployment_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class DeploymentEntity < Grape::Entity include RequestAwareEntity diff --git a/app/serializers/deployment_serializer.rb b/app/serializers/deployment_serializer.rb index cba5c3f311f..04db6b88489 100644 --- a/app/serializers/deployment_serializer.rb +++ b/app/serializers/deployment_serializer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class DeploymentSerializer < BaseSerializer entity DeploymentEntity diff --git a/app/serializers/diff_file_entity.rb b/app/serializers/diff_file_entity.rb index 61135fba97b..79844c9210a 100644 --- a/app/serializers/diff_file_entity.rb +++ b/app/serializers/diff_file_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class DiffFileEntity < Grape::Entity include RequestAwareEntity include BlobHelper diff --git a/app/serializers/diffs_entity.rb b/app/serializers/diffs_entity.rb index bb804e5347a..f75ace14d9c 100644 --- a/app/serializers/diffs_entity.rb +++ b/app/serializers/diffs_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class DiffsEntity < Grape::Entity include DiffHelper include RequestAwareEntity diff --git a/app/serializers/diffs_serializer.rb b/app/serializers/diffs_serializer.rb index 6771e10c5ac..9e5eb1699d4 100644 --- a/app/serializers/diffs_serializer.rb +++ b/app/serializers/diffs_serializer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class DiffsSerializer < BaseSerializer entity DiffsEntity end diff --git a/app/serializers/discussion_entity.rb b/app/serializers/discussion_entity.rb index 7505bbdeb3d..6f95e6f9ca1 100644 --- a/app/serializers/discussion_entity.rb +++ b/app/serializers/discussion_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class DiscussionEntity < Grape::Entity include RequestAwareEntity include NotesHelper diff --git a/app/serializers/discussion_serializer.rb b/app/serializers/discussion_serializer.rb index ed5e1224bb2..5be40e74175 100644 --- a/app/serializers/discussion_serializer.rb +++ b/app/serializers/discussion_serializer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class DiscussionSerializer < BaseSerializer entity DiscussionEntity end diff --git a/app/serializers/entity_date_helper.rb b/app/serializers/entity_date_helper.rb index 464217123b4..cc0c2abf863 100644 --- a/app/serializers/entity_date_helper.rb +++ b/app/serializers/entity_date_helper.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module EntityDateHelper include ActionView::Helpers::DateHelper include ActionView::Helpers::TagHelper @@ -50,15 +52,20 @@ module EntityDateHelper elsif entity.due_date is_upcoming = (entity.due_date - Date.today).to_i > 0 time_ago = time_ago_in_words(entity.due_date) - content = time_ago.gsub(/\d+/) { |match| "<strong>#{match}</strong>" } - content.slice!("about ") - content << " " + (is_upcoming ? _("remaining") : _("ago")) - content.html_safe + + # https://gitlab.com/gitlab-org/gitlab-ce/issues/49440 + # + # Need to improve the i18n here and do a full translation + # of the string instead of piecewise translations. + content = time_ago + .gsub(/\d+/) { |match| "<strong>#{match}</strong>" } + .remove("about ") + remaining_or_ago = is_upcoming ? _("remaining") : _("ago") + + "#{content} #{remaining_or_ago}".html_safe elsif entity.start_date && entity.start_date.past? - days = entity.elapsed_days - content = content_tag(:strong, days) - content << " #{'day'.pluralize(days)} elapsed" - content.html_safe + days = entity.elapsed_days + "#{content_tag(:strong, days)} #{'day'.pluralize(days)} elapsed".html_safe end end end diff --git a/app/serializers/entity_request.rb b/app/serializers/entity_request.rb index 456ba1174c0..49e026e8c2a 100644 --- a/app/serializers/entity_request.rb +++ b/app/serializers/entity_request.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class EntityRequest # We use EntityRequest object to collect parameters and variables # from the controller. Because options that are being passed to the entity diff --git a/app/serializers/environment_entity.rb b/app/serializers/environment_entity.rb index 83558fc6659..b18e9706db6 100644 --- a/app/serializers/environment_entity.rb +++ b/app/serializers/environment_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class EnvironmentEntity < Grape::Entity include RequestAwareEntity diff --git a/app/serializers/environment_serializer.rb b/app/serializers/environment_serializer.rb index 84722f33f59..dc1686c30c4 100644 --- a/app/serializers/environment_serializer.rb +++ b/app/serializers/environment_serializer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class EnvironmentSerializer < BaseSerializer include WithPagination diff --git a/app/serializers/group_child_entity.rb b/app/serializers/group_child_entity.rb index ee150eefd9e..f6804fe7f6a 100644 --- a/app/serializers/group_child_entity.rb +++ b/app/serializers/group_child_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class GroupChildEntity < Grape::Entity include ActionView::Helpers::NumberHelper include RequestAwareEntity diff --git a/app/serializers/group_child_serializer.rb b/app/serializers/group_child_serializer.rb index 2baef0a5703..789707c2c9b 100644 --- a/app/serializers/group_child_serializer.rb +++ b/app/serializers/group_child_serializer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class GroupChildSerializer < BaseSerializer include WithPagination diff --git a/app/serializers/group_entity.rb b/app/serializers/group_entity.rb index 6d8466da902..c46c342ee5d 100644 --- a/app/serializers/group_entity.rb +++ b/app/serializers/group_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class GroupEntity < Grape::Entity include ActionView::Helpers::NumberHelper include RequestAwareEntity diff --git a/app/serializers/group_serializer.rb b/app/serializers/group_serializer.rb index 8cf7eb63bcf..38c5757a6c1 100644 --- a/app/serializers/group_serializer.rb +++ b/app/serializers/group_serializer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class GroupSerializer < BaseSerializer include WithPagination diff --git a/app/serializers/group_variable_entity.rb b/app/serializers/group_variable_entity.rb index 62cf0b21e1e..0edab4a3092 100644 --- a/app/serializers/group_variable_entity.rb +++ b/app/serializers/group_variable_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class GroupVariableEntity < Grape::Entity expose :id expose :key diff --git a/app/serializers/group_variable_serializer.rb b/app/serializers/group_variable_serializer.rb index 8f8205924aa..ed20b240cce 100644 --- a/app/serializers/group_variable_serializer.rb +++ b/app/serializers/group_variable_serializer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class GroupVariableSerializer < BaseSerializer entity GroupVariableEntity end diff --git a/app/serializers/issuable_entity.rb b/app/serializers/issuable_entity.rb index 6f31fbd6b7c..e71bd3313fb 100644 --- a/app/serializers/issuable_entity.rb +++ b/app/serializers/issuable_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class IssuableEntity < Grape::Entity include RequestAwareEntity diff --git a/app/serializers/issuable_sidebar_entity.rb b/app/serializers/issuable_sidebar_entity.rb index 29138c803df..773d78d324c 100644 --- a/app/serializers/issuable_sidebar_entity.rb +++ b/app/serializers/issuable_sidebar_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class IssuableSidebarEntity < Grape::Entity include TimeTrackableEntity include RequestAwareEntity diff --git a/app/serializers/issue_entity.rb b/app/serializers/issue_entity.rb index 840fdbcbf14..16a477c92fa 100644 --- a/app/serializers/issue_entity.rb +++ b/app/serializers/issue_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class IssueEntity < IssuableEntity include TimeTrackableEntity diff --git a/app/serializers/issue_serializer.rb b/app/serializers/issue_serializer.rb index 2555595379b..37cf5e28396 100644 --- a/app/serializers/issue_serializer.rb +++ b/app/serializers/issue_serializer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class IssueSerializer < BaseSerializer # This overrided method takes care of which entity should be used # to serialize the `issue` based on `basic` key in `opts` param. diff --git a/app/serializers/issue_sidebar_entity.rb b/app/serializers/issue_sidebar_entity.rb index 6c823dbfe95..349ad9d1fef 100644 --- a/app/serializers/issue_sidebar_entity.rb +++ b/app/serializers/issue_sidebar_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class IssueSidebarEntity < IssuableSidebarEntity expose :assignees, using: API::Entities::UserBasic end diff --git a/app/serializers/job_entity.rb b/app/serializers/job_entity.rb index 960e7291ae6..7bc1d87dea5 100644 --- a/app/serializers/job_entity.rb +++ b/app/serializers/job_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class JobEntity < Grape::Entity include RequestAwareEntity diff --git a/app/serializers/job_group_entity.rb b/app/serializers/job_group_entity.rb index 8554de55517..0941a9d36be 100644 --- a/app/serializers/job_group_entity.rb +++ b/app/serializers/job_group_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class JobGroupEntity < Grape::Entity include RequestAwareEntity diff --git a/app/serializers/label_entity.rb b/app/serializers/label_entity.rb index 4452161051e..98743d62b50 100644 --- a/app/serializers/label_entity.rb +++ b/app/serializers/label_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class LabelEntity < Grape::Entity expose :id, if: ->(label, _) { !label.is_a?(GlobalLabel) } diff --git a/app/serializers/label_serializer.rb b/app/serializers/label_serializer.rb index ad6ba8c46c9..25b9f7de243 100644 --- a/app/serializers/label_serializer.rb +++ b/app/serializers/label_serializer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class LabelSerializer < BaseSerializer entity LabelEntity diff --git a/app/serializers/lfs_file_lock_entity.rb b/app/serializers/lfs_file_lock_entity.rb index 264a77adc3f..7961c4e666b 100644 --- a/app/serializers/lfs_file_lock_entity.rb +++ b/app/serializers/lfs_file_lock_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class LfsFileLockEntity < Grape::Entity root 'locks', 'lock' diff --git a/app/serializers/lfs_file_lock_serializer.rb b/app/serializers/lfs_file_lock_serializer.rb index ba8fb1a461d..0367097e376 100644 --- a/app/serializers/lfs_file_lock_serializer.rb +++ b/app/serializers/lfs_file_lock_serializer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class LfsFileLockSerializer < BaseSerializer entity LfsFileLockEntity end diff --git a/app/serializers/merge_request_basic_entity.rb b/app/serializers/merge_request_basic_entity.rb index 1c06691026d..f7eb74cf392 100644 --- a/app/serializers/merge_request_basic_entity.rb +++ b/app/serializers/merge_request_basic_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class MergeRequestBasicEntity < IssuableSidebarEntity expose :assignee_id expose :merge_status diff --git a/app/serializers/merge_request_basic_serializer.rb b/app/serializers/merge_request_basic_serializer.rb index cc5c664c8fa..a68b48b00db 100644 --- a/app/serializers/merge_request_basic_serializer.rb +++ b/app/serializers/merge_request_basic_serializer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class MergeRequestBasicSerializer < BaseSerializer entity MergeRequestBasicEntity end diff --git a/app/serializers/merge_request_create_entity.rb b/app/serializers/merge_request_create_entity.rb index 11234313293..e7a93004dda 100644 --- a/app/serializers/merge_request_create_entity.rb +++ b/app/serializers/merge_request_create_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class MergeRequestCreateEntity < Grape::Entity expose :iid diff --git a/app/serializers/merge_request_create_serializer.rb b/app/serializers/merge_request_create_serializer.rb index 08daf473319..b6df9ee13fc 100644 --- a/app/serializers/merge_request_create_serializer.rb +++ b/app/serializers/merge_request_create_serializer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class MergeRequestCreateSerializer < BaseSerializer entity MergeRequestCreateEntity end diff --git a/app/serializers/merge_request_diff_entity.rb b/app/serializers/merge_request_diff_entity.rb index 32c761b45ac..433bfe60474 100644 --- a/app/serializers/merge_request_diff_entity.rb +++ b/app/serializers/merge_request_diff_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class MergeRequestDiffEntity < Grape::Entity include Gitlab::Routing include GitHelper diff --git a/app/serializers/merge_request_metrics_entity.rb b/app/serializers/merge_request_metrics_entity.rb index 3548107ac16..1c9db08d103 100644 --- a/app/serializers/merge_request_metrics_entity.rb +++ b/app/serializers/merge_request_metrics_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class MergeRequestMetricsEntity < Grape::Entity expose :latest_closed_at, as: :closed_at expose :merged_at diff --git a/app/serializers/merge_request_serializer.rb b/app/serializers/merge_request_serializer.rb index caf193bdae3..1f8c830e1aa 100644 --- a/app/serializers/merge_request_serializer.rb +++ b/app/serializers/merge_request_serializer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class MergeRequestSerializer < BaseSerializer # This overrided method takes care of which entity should be used # to serialize the `merge_request` based on `serializer` key in `opts` param. diff --git a/app/serializers/merge_request_user_entity.rb b/app/serializers/merge_request_user_entity.rb index 33fc7b724d5..fd2d2897113 100644 --- a/app/serializers/merge_request_user_entity.rb +++ b/app/serializers/merge_request_user_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class MergeRequestUserEntity < UserEntity include RequestAwareEntity include BlobHelper diff --git a/app/serializers/merge_request_widget_entity.rb b/app/serializers/merge_request_widget_entity.rb index a78bd77cf7c..4fe04e4b206 100644 --- a/app/serializers/merge_request_widget_entity.rb +++ b/app/serializers/merge_request_widget_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class MergeRequestWidgetEntity < IssuableEntity expose :state expose :in_progress_merge_commit_sha diff --git a/app/serializers/note_attachment_entity.rb b/app/serializers/note_attachment_entity.rb index 1ad50568ab9..dc801e2bf4e 100644 --- a/app/serializers/note_attachment_entity.rb +++ b/app/serializers/note_attachment_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class NoteAttachmentEntity < Grape::Entity expose :url expose :filename diff --git a/app/serializers/note_entity.rb b/app/serializers/note_entity.rb index 0e1f94a9f61..daa5c24d0f5 100644 --- a/app/serializers/note_entity.rb +++ b/app/serializers/note_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class NoteEntity < API::Entities::Note include RequestAwareEntity include NotesHelper diff --git a/app/serializers/note_user_entity.rb b/app/serializers/note_user_entity.rb index 7289f3a0222..b00dfa7d353 100644 --- a/app/serializers/note_user_entity.rb +++ b/app/serializers/note_user_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class NoteUserEntity < UserEntity unexpose :web_url end diff --git a/app/serializers/pipeline_details_entity.rb b/app/serializers/pipeline_details_entity.rb index 8ba9cac53c4..3b56767f774 100644 --- a/app/serializers/pipeline_details_entity.rb +++ b/app/serializers/pipeline_details_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class PipelineDetailsEntity < PipelineEntity expose :details do expose :ordered_stages, as: :stages, using: StageEntity diff --git a/app/serializers/pipeline_entity.rb b/app/serializers/pipeline_entity.rb index f782b411b84..6cf1925adda 100644 --- a/app/serializers/pipeline_entity.rb +++ b/app/serializers/pipeline_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class PipelineEntity < Grape::Entity include RequestAwareEntity diff --git a/app/serializers/pipeline_serializer.rb b/app/serializers/pipeline_serializer.rb index 17a022539bb..4a33160afa1 100644 --- a/app/serializers/pipeline_serializer.rb +++ b/app/serializers/pipeline_serializer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class PipelineSerializer < BaseSerializer include WithPagination entity PipelineDetailsEntity diff --git a/app/serializers/project_entity.rb b/app/serializers/project_entity.rb index b3e5fd21e97..60c4ba135d6 100644 --- a/app/serializers/project_entity.rb +++ b/app/serializers/project_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class ProjectEntity < Grape::Entity include RequestAwareEntity diff --git a/app/serializers/project_mirror_entity.rb b/app/serializers/project_mirror_entity.rb index a9c08ac021a..8aba244cd11 100644 --- a/app/serializers/project_mirror_entity.rb +++ b/app/serializers/project_mirror_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class ProjectMirrorEntity < Grape::Entity expose :id diff --git a/app/serializers/project_note_entity.rb b/app/serializers/project_note_entity.rb index e541bfbee8d..d7c4d0aacc6 100644 --- a/app/serializers/project_note_entity.rb +++ b/app/serializers/project_note_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class ProjectNoteEntity < NoteEntity expose :human_access do |note| note.project.team.human_max_access(note.author_id) diff --git a/app/serializers/project_note_serializer.rb b/app/serializers/project_note_serializer.rb index 763ad0bdb3f..2182904e815 100644 --- a/app/serializers/project_note_serializer.rb +++ b/app/serializers/project_note_serializer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class ProjectNoteSerializer < BaseSerializer entity ProjectNoteEntity end diff --git a/app/serializers/project_serializer.rb b/app/serializers/project_serializer.rb index 74de1e79a8f..23b96c2fc9e 100644 --- a/app/serializers/project_serializer.rb +++ b/app/serializers/project_serializer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class ProjectSerializer < BaseSerializer entity ProjectEntity end diff --git a/app/serializers/request_aware_entity.rb b/app/serializers/request_aware_entity.rb index d53fcfb8c1b..1524c1291d8 100644 --- a/app/serializers/request_aware_entity.rb +++ b/app/serializers/request_aware_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module RequestAwareEntity extend ActiveSupport::Concern diff --git a/app/serializers/runner_entity.rb b/app/serializers/runner_entity.rb index db26eadab2d..04ec80e0efa 100644 --- a/app/serializers/runner_entity.rb +++ b/app/serializers/runner_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class RunnerEntity < Grape::Entity include RequestAwareEntity diff --git a/app/serializers/stage_entity.rb b/app/serializers/stage_entity.rb index 2516df70ad9..00e6d32ee3a 100644 --- a/app/serializers/stage_entity.rb +++ b/app/serializers/stage_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class StageEntity < Grape::Entity include RequestAwareEntity diff --git a/app/serializers/stage_serializer.rb b/app/serializers/stage_serializer.rb index 091d8e91e43..11fb0d3f852 100644 --- a/app/serializers/stage_serializer.rb +++ b/app/serializers/stage_serializer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class StageSerializer < BaseSerializer include WithPagination diff --git a/app/serializers/status_entity.rb b/app/serializers/status_entity.rb index 47df7f9dcf9..306c30f0323 100644 --- a/app/serializers/status_entity.rb +++ b/app/serializers/status_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class StatusEntity < Grape::Entity include RequestAwareEntity diff --git a/app/serializers/submodule_entity.rb b/app/serializers/submodule_entity.rb index ed1f1ae0ef0..e475a4f301f 100644 --- a/app/serializers/submodule_entity.rb +++ b/app/serializers/submodule_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class SubmoduleEntity < Grape::Entity include RequestAwareEntity diff --git a/app/serializers/time_trackable_entity.rb b/app/serializers/time_trackable_entity.rb index e81cd7bec72..613d19703a4 100644 --- a/app/serializers/time_trackable_entity.rb +++ b/app/serializers/time_trackable_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module TimeTrackableEntity extend ActiveSupport::Concern extend Grape diff --git a/app/serializers/tree_entity.rb b/app/serializers/tree_entity.rb index 9f1b485347f..9b7dc80e1d9 100644 --- a/app/serializers/tree_entity.rb +++ b/app/serializers/tree_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class TreeEntity < Grape::Entity include RequestAwareEntity diff --git a/app/serializers/tree_root_entity.rb b/app/serializers/tree_root_entity.rb index 496f070ddbd..f1cfcd943d8 100644 --- a/app/serializers/tree_root_entity.rb +++ b/app/serializers/tree_root_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # TODO: Inherit from TreeEntity, when `Tree` implements `id` and `name` like `Gitlab::Git::Tree`. class TreeRootEntity < Grape::Entity include RequestAwareEntity diff --git a/app/serializers/tree_serializer.rb b/app/serializers/tree_serializer.rb index 713ade23bc9..536b8ab1ae2 100644 --- a/app/serializers/tree_serializer.rb +++ b/app/serializers/tree_serializer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class TreeSerializer < BaseSerializer entity TreeRootEntity end diff --git a/app/serializers/user_entity.rb b/app/serializers/user_entity.rb index 876512b12dc..6236d66ff4a 100644 --- a/app/serializers/user_entity.rb +++ b/app/serializers/user_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class UserEntity < API::Entities::UserBasic include RequestAwareEntity diff --git a/app/serializers/user_serializer.rb b/app/serializers/user_serializer.rb index 49a71ebac61..2111e1b5667 100644 --- a/app/serializers/user_serializer.rb +++ b/app/serializers/user_serializer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class UserSerializer < BaseSerializer entity UserEntity end diff --git a/app/serializers/variable_entity.rb b/app/serializers/variable_entity.rb index d576745c073..85cf367fe51 100644 --- a/app/serializers/variable_entity.rb +++ b/app/serializers/variable_entity.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class VariableEntity < Grape::Entity expose :id expose :key diff --git a/app/serializers/variable_serializer.rb b/app/serializers/variable_serializer.rb index 32ae82ab51c..586666cad8e 100644 --- a/app/serializers/variable_serializer.rb +++ b/app/serializers/variable_serializer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class VariableSerializer < BaseSerializer entity VariableEntity end diff --git a/app/services/projects/import_service.rb b/app/services/projects/import_service.rb index e560d40371e..0c426faa22d 100644 --- a/app/services/projects/import_service.rb +++ b/app/services/projects/import_service.rb @@ -25,7 +25,7 @@ module Projects success rescue => e - error("Error importing repository #{project.import_url} into #{project.full_path} - #{e.message}") + error("Error importing repository #{project.safe_import_url} into #{project.full_path} - #{e.message}") end private diff --git a/app/services/users/build_service.rb b/app/services/users/build_service.rb index c69b46cab5a..acc2fa153ae 100644 --- a/app/services/users/build_service.rb +++ b/app/services/users/build_service.rb @@ -64,7 +64,8 @@ module Users :theme_id, :twitter, :username, - :website_url + :website_url, + :private_profile ] end diff --git a/app/uploaders/import_export_uploader.rb b/app/uploaders/import_export_uploader.rb index 213ac5c8011..7c45ba5ca95 100644 --- a/app/uploaders/import_export_uploader.rb +++ b/app/uploaders/import_export_uploader.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class ImportExportUploader < AttachmentUploader EXTENSION_WHITELIST = %w[tar.gz].freeze diff --git a/app/views/admin/dashboard/index.html.haml b/app/views/admin/dashboard/index.html.haml index 18f2c1a509f..fac61f9d249 100644 --- a/app/views/admin/dashboard/index.html.haml +++ b/app/views/admin/dashboard/index.html.haml @@ -91,10 +91,10 @@ %span.light.float-right = boolean_to_icon gravatar_enabled? - omniauth = "OmniAuth" - %p{ "aria-label" => "#{omniauth}: status " + (Gitlab.config.omniauth.enabled ? "on" : "off") } + %p{ "aria-label" => "#{omniauth}: status " + (Gitlab::Auth.omniauth_enabled? ? "on" : "off") } = omniauth %span.light.float-right - = boolean_to_icon Gitlab.config.omniauth.enabled + = boolean_to_icon Gitlab::Auth.omniauth_enabled? - reply_email = "Reply by email" %p{ "aria-label" => "#{reply_email}: status " + (Gitlab::IncomingEmail.enabled? ? "on" : "off") } = reply_email diff --git a/app/views/admin/runners/show.html.haml b/app/views/admin/runners/show.html.haml index 62b7a4cbd07..62be38e9dd2 100644 --- a/app/views/admin/runners/show.html.haml +++ b/app/views/admin/runners/show.html.haml @@ -11,7 +11,6 @@ - add_to_breadcrumbs _("Runners"), admin_runners_path - breadcrumb_title "##{@runner.id}" -- @no_container = true - if @runner.instance_type? .bs-callout.bs-callout-success diff --git a/app/views/import/bitbucket_server/new.html.haml b/app/views/import/bitbucket_server/new.html.haml index 11bd53516a6..12e0b917de5 100644 --- a/app/views/import/bitbucket_server/new.html.haml +++ b/app/views/import/bitbucket_server/new.html.haml @@ -13,7 +13,7 @@ .form-group.row = label_tag :bitbucket_server_url, 'Bitbucket Server URL', class: 'col-form-label col-md-2' .col-md-4 - = text_field_tag :bitbucket_server_url, '', class: 'form-control append-right-8', placeholder: _('URL for Bitbucket Server'), size: 40 + = text_field_tag :bitbucket_server_url, '', class: 'form-control append-right-8', placeholder: _('https://your-bitbucket-server'), size: 40 .form-group.row = label_tag :bitbucket_server_url, 'Username', class: 'col-form-label col-md-2' .col-md-4 diff --git a/app/views/layouts/_recaptcha_verification.html.haml b/app/views/layouts/_recaptcha_verification.html.haml index e6f87ddd383..3405fb9d5ef 100644 --- a/app/views/layouts/_recaptcha_verification.html.haml +++ b/app/views/layouts/_recaptcha_verification.html.haml @@ -1,10 +1,10 @@ - humanized_resource_name = spammable.class.model_name.human.downcase %h3.page-title - Anti-spam verification + = _('Anti-spam verification') %hr %p - #{"We detected potential spam in the #{humanized_resource_name}. Please solve the reCAPTCHA to proceed."} + = _("We detected potential spam in the %{humanized_resource_name}. Please solve the reCAPTCHA to proceed.") % { humanized_resource_name: humanized_resource_name } = render 'shared/recaptcha_form', spammable: spammable diff --git a/app/views/layouts/_search.html.haml b/app/views/layouts/_search.html.haml index 91f796adb2e..556ad8cf306 100644 --- a/app/views/layouts/_search.html.haml +++ b/app/views/layouts/_search.html.haml @@ -1,7 +1,7 @@ - if controller.controller_path =~ /^groups/ && @group.persisted? - - label = 'This group' + - label = _('This group') - if controller.controller_path =~ /^projects/ && @project.persisted? - - label = 'This project' + - label = _('This project') - if @group && @group.persisted? && @group.path - group_data_attrs = { group_path: j(@group.path), name: @group.name, issues_path: issues_group_path(j(@group.path)), mr_path: merge_requests_group_path(j(@group.path)) } - if @project && @project.persisted? @@ -13,21 +13,21 @@ .location-badge= label .search-input-wrap .dropdown{ data: { url: search_autocomplete_path } } - = search_field_tag 'search', nil, placeholder: 'Search', + = search_field_tag 'search', nil, placeholder: _('Search'), class: 'search-input dropdown-menu-toggle no-outline js-search-dashboard-options', spellcheck: false, tabindex: '1', autocomplete: 'off', data: { issues_path: issues_dashboard_path, mr_path: merge_requests_dashboard_path }, - aria: { label: 'Search' } + aria: { label: _('Search') } %button.hidden.js-dropdown-search-toggle{ type: 'button', data: { toggle: 'dropdown' } } .dropdown-menu.dropdown-select = dropdown_content do %ul %li.dropdown-menu-empty-item %a - Loading... + = _('Loading...') = dropdown_loading = sprite_icon('search', size: 16, css_class: 'search-icon') = sprite_icon('close', size: 16, css_class: 'clear-icon js-clear-input') diff --git a/app/views/layouts/admin.html.haml b/app/views/layouts/admin.html.haml index 8595157a997..31259b8ac25 100644 --- a/app/views/layouts/admin.html.haml +++ b/app/views/layouts/admin.html.haml @@ -1,5 +1,5 @@ -- page_title "Admin Area" -- header_title "Admin Area", admin_root_path +- page_title _("Admin Area") +- header_title _("Admin Area"), admin_root_path - nav "admin" - @left_sidebar = true diff --git a/app/views/layouts/dashboard.html.haml b/app/views/layouts/dashboard.html.haml index cb96bcc2cf4..489ef245a4d 100644 --- a/app/views/layouts/dashboard.html.haml +++ b/app/views/layouts/dashboard.html.haml @@ -1,5 +1,5 @@ -- page_title "Dashboard" -- header_title "Dashboard", root_path unless header_title +- page_title _("Dashboard") +- header_title _("Dashboard"), root_path unless header_title - sidebar "dashboard" = render template: "layouts/application" diff --git a/app/views/layouts/devise.html.haml b/app/views/layouts/devise.html.haml index 81f35615555..43bd07679ba 100644 --- a/app/views/layouts/devise.html.haml +++ b/app/views/layouts/devise.html.haml @@ -17,12 +17,11 @@ - if current_appearance&.description? = brand_text - else - %h3 Open source software to collaborate on code + %h3 + = _('Open source software to collaborate on code') %p - Manage Git repositories with fine-grained access controls that keep your code secure. - Perform code reviews and enhance collaboration with merge requests. - Each project can also have an issue tracker and a wiki. + = _('Manage Git repositories with fine-grained access controls that keep your code secure. Perform code reviews and enhance collaboration with merge requests. Each project can also have an issue tracker and a wiki.') - if Gitlab::CurrentSettings.sign_in_text.present? = markdown_field(Gitlab::CurrentSettings.current_application_settings, :sign_in_text) @@ -32,6 +31,6 @@ %hr.footer-fixed .container.footer-container .footer-links - = link_to "Explore", explore_root_path - = link_to "Help", help_path - = link_to "About GitLab", "https://about.gitlab.com/" + = link_to _("Explore"), explore_root_path + = link_to _("Help"), help_path + = link_to _("About GitLab"), "https://about.gitlab.com/" diff --git a/app/views/layouts/devise_empty.html.haml b/app/views/layouts/devise_empty.html.haml index 52805e0da73..663e5b24368 100644 --- a/app/views/layouts/devise_empty.html.haml +++ b/app/views/layouts/devise_empty.html.haml @@ -12,6 +12,6 @@ %hr .container .footer-links - = link_to "Explore", explore_root_path - = link_to "Help", help_path - = link_to "About GitLab", "https://about.gitlab.com/" + = link_to _("Explore"), explore_root_path + = link_to _("Help"), help_path + = link_to _("About GitLab"), "https://about.gitlab.com/" diff --git a/app/views/layouts/explore.html.haml b/app/views/layouts/explore.html.haml index df65792be73..2ab9e55441b 100644 --- a/app/views/layouts/explore.html.haml +++ b/app/views/layouts/explore.html.haml @@ -1,5 +1,5 @@ -- page_title "Explore" +- page_title = _("Explore") - unless current_user - - header_title "Explore GitLab", explore_root_path + - header_title = _("Explore GitLab"), explore_root_path = render template: "layouts/application" diff --git a/app/views/layouts/group_settings.html.haml b/app/views/layouts/group_settings.html.haml index 66b115e36de..14c5f0ce04c 100644 --- a/app/views/layouts/group_settings.html.haml +++ b/app/views/layouts/group_settings.html.haml @@ -1,4 +1,4 @@ -- page_title "Settings" +- page_title = _("Settings") - nav "group" = render template: "layouts/group" diff --git a/app/views/layouts/header/_default.html.haml b/app/views/layouts/header/_default.html.haml index 3aa8eb18bf3..97c04dda8cb 100644 --- a/app/views/layouts/header/_default.html.haml +++ b/app/views/layouts/header/_default.html.haml @@ -4,7 +4,7 @@ .header-content .title-container %h1.title - = link_to root_path, title: 'Dashboard', id: 'logo' do + = link_to root_path, title: _('Dashboard'), id: 'logo' do = brand_header_logo - logo_text = brand_header_logo_type - if logo_text.present? @@ -24,26 +24,26 @@ %li.nav-item.d-none.d-sm-none.d-md-block.m-auto = render 'layouts/search' unless current_controller?(:search) %li.nav-item.d-inline-block.d-sm-none.d-md-none - = link_to search_path, title: 'Search', aria: { label: "Search" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do + = link_to search_path, title: _('Search'), aria: { label: _("Search") }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do = sprite_icon('search', size: 16) - if header_link?(:issues) = nav_link(path: 'dashboard#issues', html_options: { class: "user-counter" }) do - = link_to assigned_issues_dashboard_path, title: 'Issues', class: 'dashboard-shortcuts-issues', aria: { label: "Issues" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do + = link_to assigned_issues_dashboard_path, title: _('Issues'), class: 'dashboard-shortcuts-issues', aria: { label: _("Issues") }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do = sprite_icon('issues', size: 16) - issues_count = assigned_issuables_count(:issues) %span.badge.badge-pill.issues-count{ class: ('hidden' if issues_count.zero?) } = number_with_delimiter(issues_count) - if header_link?(:merge_requests) = nav_link(path: 'dashboard#merge_requests', html_options: { class: "user-counter" }) do - = link_to assigned_mrs_dashboard_path, title: 'Merge requests', class: 'dashboard-shortcuts-merge_requests', aria: { label: "Merge requests" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do + = link_to assigned_mrs_dashboard_path, title: _('Merge requests'), class: 'dashboard-shortcuts-merge_requests', aria: { label: _("Merge requests") }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do = sprite_icon('git-merge', size: 16) - merge_requests_count = assigned_issuables_count(:merge_requests) %span.badge.badge-pill.merge-requests-count{ class: ('hidden' if merge_requests_count.zero?) } = number_with_delimiter(merge_requests_count) - if header_link?(:todos) = nav_link(controller: 'dashboard/todos', html_options: { class: "user-counter" }) do - = link_to dashboard_todos_path, title: 'Todos', aria: { label: "Todos" }, class: 'shortcuts-todos', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do + = link_to dashboard_todos_path, title: _('Todos'), aria: { label: _("Todos") }, class: 'shortcuts-todos', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do = sprite_icon('todo-done', size: 16) %span.badge.badge-pill.todos-count{ class: ('hidden' if todos_pending_count.zero?) } = todos_count_format(todos_pending_count) @@ -56,16 +56,16 @@ = render 'layouts/header/current_user_dropdown' - if header_link?(:admin_impersonation) %li.nav-item.impersonation - = link_to admin_impersonation_path, class: 'nav-link impersonation-btn', method: :delete, title: "Stop impersonation", aria: { label: 'Stop impersonation' }, data: { toggle: 'tooltip', placement: 'bottom', container: 'body' } do + = link_to admin_impersonation_path, class: 'nav-link impersonation-btn', method: :delete, title: _("Stop impersonation"), aria: { label: _('Stop impersonation') }, data: { toggle: 'tooltip', placement: 'bottom', container: 'body' } do = icon('user-secret') - if header_link?(:sign_in) %li.nav-item %div - - sign_in_text = allow_signup? ? 'Sign in / Register' : 'Sign in' + - sign_in_text = allow_signup? ? _('Sign in / Register') : _('Sign in') = link_to sign_in_text, new_session_path(:user, redirect_to_referer: 'yes'), class: 'btn btn-sign-in' %button.navbar-toggler.d-block.d-sm-none{ type: 'button' } - %span.sr-only Toggle navigation + %span.sr-only= _("Toggle navigation") = sprite_icon('more', size: 12, css_class: 'more-icon js-navbar-toggle-right') = sprite_icon('close', size: 12, css_class: 'close-icon js-navbar-toggle-left') diff --git a/app/views/layouts/header/_new_dropdown.haml b/app/views/layouts/header/_new_dropdown.haml index 792291bde75..e134f416c70 100644 --- a/app/views/layouts/header/_new_dropdown.haml +++ b/app/views/layouts/header/_new_dropdown.haml @@ -1,5 +1,5 @@ %li.header-new.dropdown - = link_to new_project_path, class: "header-new-dropdown-toggle has-tooltip qa-new-menu-toggle", title: "New...", ref: 'tooltip', aria: { label: "New..." }, data: { toggle: 'dropdown', placement: 'bottom', container: 'body', display: 'static' } do + = link_to new_project_path, class: "header-new-dropdown-toggle has-tooltip qa-new-menu-toggle", title: _("New..."), ref: 'tooltip', aria: { label: _("New...") }, data: { toggle: 'dropdown', placement: 'bottom', container: 'body', display: 'static' } do = sprite_icon('plus-square', size: 16) = sprite_icon('angle-down', css_class: 'caret-down') .dropdown-menu.dropdown-menu-right @@ -8,13 +8,14 @@ - create_group_project = can?(current_user, :create_projects, @group) - create_group_subgroup = can?(current_user, :create_subgroup, @group) - if create_group_project || create_group_subgroup - %li.dropdown-bold-header This group + %li.dropdown-bold-header + = _('This group') - if create_group_project %li.header-new-group-project - = link_to 'New project', new_project_path(namespace_id: @group.id) + = link_to _('New project'), new_project_path(namespace_id: @group.id) - if create_group_subgroup %li - = link_to 'New subgroup', new_group_path(parent_id: @group.id) + = link_to _('New subgroup'), new_group_path(parent_id: @group.id) %li.divider %li.dropdown-bold-header GitLab @@ -23,23 +24,24 @@ - merge_project = merge_request_source_project_for_project(@project) - create_project_snippet = can?(current_user, :create_project_snippet, @project) - if create_project_issue || merge_project || create_project_snippet - %li.dropdown-bold-header This project + %li.dropdown-bold-header + = _('This project') - if create_project_issue %li - = link_to 'New issue', new_project_issue_path(@project) + = link_to _('New issue'), new_project_issue_path(@project) - if merge_project %li - = link_to 'New merge request', project_new_merge_request_path(merge_project) + = link_to _('New merge request'), project_new_merge_request_path(merge_project) - if create_project_snippet %li.header-new-project-snippet - = link_to 'New snippet', new_project_snippet_path(@project) + = link_to _('New snippet'), new_project_snippet_path(@project) %li.divider %li.dropdown-bold-header GitLab - if current_user.can_create_project? %li - = link_to 'New project', new_project_path, class: 'qa-global-new-project-link' + = link_to _('New project'), new_project_path, class: 'qa-global-new-project-link' - if current_user.can_create_group? %li - = link_to 'New group', new_group_path + = link_to _('New group'), new_group_path %li - = link_to 'New snippet', new_snippet_path + = link_to _('New snippet'), new_snippet_path diff --git a/app/views/layouts/help.html.haml b/app/views/layouts/help.html.haml index 78927bfffcd..a913bea0c93 100644 --- a/app/views/layouts/help.html.haml +++ b/app/views/layouts/help.html.haml @@ -1,5 +1,5 @@ -- @breadcrumb_title = "Help" -- page_title "Help" -- header_title "Help", help_path +- @breadcrumb_title = _("Help") +- page_title _("Help") +- header_title _("Help"), help_path = render template: "layouts/application" diff --git a/app/views/layouts/koding.html.haml b/app/views/layouts/koding.html.haml index 22319bba745..45ccd38f687 100644 --- a/app/views/layouts/koding.html.haml +++ b/app/views/layouts/koding.html.haml @@ -1,5 +1,5 @@ -- page_title "Koding" -- page_description "Koding Dashboard" -- header_title "Koding", koding_path +- page_title _("Koding") +- page_description _("Koding Dashboard") +- header_title _("Koding"), koding_path = render template: "layouts/application" diff --git a/app/views/layouts/mailer.text.erb b/app/views/layouts/mailer.text.erb index 8e20c4a4b2a..8e11174f8d7 100644 --- a/app/views/layouts/mailer.text.erb +++ b/app/views/layouts/mailer.text.erb @@ -1,4 +1,4 @@ <%= yield -%> -- <%# signature marker %> -You're receiving this email because of your account on <%= Gitlab.config.gitlab.host %>. +<%= _("You're receiving this email because of your account on %{host}.") % { host: Gitlab.config.gitlab.host } %> diff --git a/app/views/layouts/mailer/devise.html.haml b/app/views/layouts/mailer/devise.html.haml index 054b2c2fa26..beaaaa5cd68 100644 --- a/app/views/layouts/mailer/devise.html.haml +++ b/app/views/layouts/mailer/devise.html.haml @@ -3,17 +3,17 @@ %tr %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:13px;line-height:1.6;color:#5c5c5c;" } %div - Everyone can contribute + = _('Everyone can contribute') %div - = link_to 'Blog', 'https://about.gitlab.com/blog/', style: "color:#3777b0;text-decoration:none;" + = link_to _('Blog'), 'https://about.gitlab.com/blog/', style: "color:#3777b0;text-decoration:none;" · - = link_to 'Twitter', 'https://twitter.com/gitlab', style: "color:#3777b0;text-decoration:none;" + = link_to _('Twitter'), 'https://twitter.com/gitlab', style: "color:#3777b0;text-decoration:none;" · - = link_to 'Facebook', 'https://www.facebook.com/gitlab/', style: "color:#3777b0;text-decoration:none;" + = link_to _('Facebook'), 'https://www.facebook.com/gitlab/', style: "color:#3777b0;text-decoration:none;" · - = link_to 'YouTube', 'https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg', style: "color:#3777b0;text-decoration:none;" + = link_to _('YouTube'), 'https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg', style: "color:#3777b0;text-decoration:none;" · - = link_to 'LinkedIn', 'https://www.linkedin.com/company/gitlab-com', style: "color:#3777b0;text-decoration:none;" + = link_to _('LinkedIn'), 'https://www.linkedin.com/company/gitlab-com', style: "color:#3777b0;text-decoration:none;" = render layout: 'layouts/mailer' do %tr diff --git a/app/views/layouts/nav/_breadcrumbs.html.haml b/app/views/layouts/nav/_breadcrumbs.html.haml index 002922e13f1..f53bd2b5e4d 100644 --- a/app/views/layouts/nav/_breadcrumbs.html.haml +++ b/app/views/layouts/nav/_breadcrumbs.html.haml @@ -5,7 +5,7 @@ .breadcrumbs-container - if defined?(@left_sidebar) = button_tag class: 'toggle-mobile-nav', type: 'button' do - %span.sr-only Open sidebar + %span.sr-only= _("Open sidebar") = icon ('bars') .breadcrumbs-links.js-title-container %ul.list-unstyled.breadcrumbs-list.js-breadcrumbs-list diff --git a/app/views/layouts/nav/_dashboard.html.haml b/app/views/layouts/nav/_dashboard.html.haml index 4029287fc0e..a71a4b13a7e 100644 --- a/app/views/layouts/nav/_dashboard.html.haml +++ b/app/views/layouts/nav/_dashboard.html.haml @@ -2,7 +2,7 @@ - if dashboard_nav_link?(:projects) = nav_link(path: ['root#index', 'projects#trending', 'projects#starred', 'dashboard/projects#index'], html_options: { id: 'nav-projects-dropdown', class: "home dropdown header-projects qa-projects-dropdown" }) do %button{ type: 'button', data: { toggle: "dropdown" } } - Projects + = _('Projects') = sprite_icon('angle-down', css_class: 'caret-down') .dropdown-menu.frequent-items-dropdown-menu = render "layouts/nav/projects_dropdown/show" @@ -10,68 +10,68 @@ - if dashboard_nav_link?(:groups) = nav_link(controller: ['dashboard/groups', 'explore/groups'], html_options: { id: 'nav-groups-dropdown', class: "home dropdown header-groups qa-groups-dropdown" }) do %button{ type: 'button', data: { toggle: "dropdown" } } - Groups + = _('Groups') = sprite_icon('angle-down', css_class: 'caret-down') .dropdown-menu.frequent-items-dropdown-menu = render "layouts/nav/groups_dropdown/show" - if dashboard_nav_link?(:activity) = nav_link(path: 'dashboard#activity', html_options: { class: "d-none d-lg-block d-xl-block" }) do - = link_to activity_dashboard_path, class: 'dashboard-shortcuts-activity', title: 'Activity' do - Activity + = link_to activity_dashboard_path, class: 'dashboard-shortcuts-activity', title: _('Activity') do + = _('Activity') - if dashboard_nav_link?(:milestones) = nav_link(controller: 'dashboard/milestones', html_options: { class: "d-none d-lg-block d-xl-block" }) do - = link_to dashboard_milestones_path, class: 'dashboard-shortcuts-milestones', title: 'Milestones' do - Milestones + = link_to dashboard_milestones_path, class: 'dashboard-shortcuts-milestones', title: _('Milestones') do + = _('Milestones') - if dashboard_nav_link?(:snippets) = nav_link(controller: 'dashboard/snippets', html_options: { class: "d-none d-lg-block d-xl-block" }) do - = link_to dashboard_snippets_path, class: 'dashboard-shortcuts-snippets', title: 'Snippets' do - Snippets + = link_to dashboard_snippets_path, class: 'dashboard-shortcuts-snippets', title: _('Snippets') do + = _('Snippets') - if any_dashboard_nav_link?([:groups, :milestones, :activity, :snippets]) %li.header-more.dropdown.d-lg-none.d-xl-none %a{ href: "#", data: { toggle: "dropdown" } } - More + = _('More') = sprite_icon('angle-down', css_class: 'caret-down') .dropdown-menu %ul - if dashboard_nav_link?(:activity) = nav_link(path: 'dashboard#activity') do - = link_to activity_dashboard_path, title: 'Activity' do - Activity + = link_to activity_dashboard_path, title: _('Activity') do + = _('Activity') - if dashboard_nav_link?(:milestones) = nav_link(controller: 'dashboard/milestones') do - = link_to dashboard_milestones_path, class: 'dashboard-shortcuts-milestones', title: 'Milestones' do - Milestones + = link_to dashboard_milestones_path, class: 'dashboard-shortcuts-milestones', title: _('Milestones') do + = _('Milestones') - if dashboard_nav_link?(:snippets) = nav_link(controller: 'dashboard/snippets') do - = link_to dashboard_snippets_path, class: 'dashboard-shortcuts-snippets', title: 'Snippets' do - Snippets + = link_to dashboard_snippets_path, class: 'dashboard-shortcuts-snippets', title: _('Snippets') do + = _('Snippets') -# Shortcut to Dashboard > Projects - if dashboard_nav_link?(:projects) %li.hidden - = link_to dashboard_projects_path, title: 'Projects', class: 'dashboard-shortcuts-projects' do - Projects + = link_to dashboard_projects_path, title: _('Projects'), class: 'dashboard-shortcuts-projects' do + = _('Projects') - if current_controller?('ide') %li.line-separator.d-none.d-sm-block = nav_link(controller: 'ide') do - = link_to '#', class: 'dashboard-shortcuts-web-ide', title: 'Web IDE' do - Web IDE + = link_to '#', class: 'dashboard-shortcuts-web-ide', title: _('Web IDE') do + = _('Web IDE') - if current_user.admin? || Gitlab::Sherlock.enabled? %li.line-separator.d-none.d-sm-block - if current_user.admin? = nav_link(controller: 'admin/dashboard') do - = link_to admin_root_path, class: 'admin-icon qa-admin-area-link', title: 'Admin area', aria: { label: "Admin area" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do + = link_to admin_root_path, class: 'admin-icon qa-admin-area-link', title: _('Admin area'), aria: { label: _("Admin area") }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do = sprite_icon('admin', size: 18) - if Gitlab::Sherlock.enabled? %li - = link_to sherlock_transactions_path, class: 'admin-icon', title: 'Sherlock Transactions', + = link_to sherlock_transactions_path, class: 'admin-icon', title: _('Sherlock Transactions'), data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do = icon('tachometer fw') diff --git a/app/views/layouts/nav/_explore.html.haml b/app/views/layouts/nav/_explore.html.haml index 50bde9d1754..7d18cd8978b 100644 --- a/app/views/layouts/nav/_explore.html.haml +++ b/app/views/layouts/nav/_explore.html.haml @@ -1,15 +1,15 @@ %ul.list-unstyled.navbar-sub-nav - if explore_nav_link?(:projects) = nav_link(path: ['dashboard#show', 'root#show', 'projects#trending', 'projects#starred', 'projects#index'], html_options: {class: 'home'}) do - = link_to explore_root_path, title: 'Projects', class: 'dashboard-shortcuts-projects' do - Projects + = link_to explore_root_path, title: _('Projects'), class: 'dashboard-shortcuts-projects' do + = _('Projects') - if explore_nav_link?(:groups) = nav_link(controller: [:groups, 'groups/milestones', 'groups/group_members']) do - = link_to explore_groups_path, title: 'Groups', class: 'dashboard-shortcuts-groups' do - Groups + = link_to explore_groups_path, title: _('Groups'), class: 'dashboard-shortcuts-groups' do + = _('Groups') - if explore_nav_link?(:snippets) = nav_link(controller: :snippets) do - = link_to explore_snippets_path, title: 'Snippets', class: 'dashboard-shortcuts-snippets' do - Snippets + = link_to explore_snippets_path, title: _('Snippets'), class: 'dashboard-shortcuts-snippets' do + = _('Snippets') %li - = link_to "Help", help_path, title: 'About GitLab CE' + = link_to _("Help"), help_path, title: _('About GitLab CE') diff --git a/app/views/layouts/nav/sidebar/_admin.html.haml b/app/views/layouts/nav/sidebar/_admin.html.haml index 4c73da4c75b..0047efa363d 100644 --- a/app/views/layouts/nav/sidebar/_admin.html.haml +++ b/app/views/layouts/nav/sidebar/_admin.html.haml @@ -1,142 +1,143 @@ .nav-sidebar{ class: ("sidebar-collapsed-desktop" if collapsed_sidebar?) } .nav-sidebar-inner-scroll .context-header - = link_to admin_root_path, title: 'Admin Overview' do + = link_to admin_root_path, title: _('Admin Overview') do .avatar-container.s40.settings-avatar = sprite_icon('admin', size: 24) - .sidebar-context-title Admin Area + .sidebar-context-title + = _('Admin Area') %ul.sidebar-top-level-items = nav_link(controller: %w(dashboard admin projects users groups jobs runners gitaly_servers cohorts conversational_development_index), html_options: {class: 'home'}) do = link_to admin_root_path, class: 'shortcuts-tree' do .nav-icon-container = sprite_icon('overview') %span.nav-item-name - Overview + = _('Overview') %ul.sidebar-sub-level-items = nav_link(controller: %w(dashboard admin projects users groups jobs runners gitaly_servers cohorts conversational_development_index), html_options: { class: "fly-out-top-item" } ) do = link_to admin_root_path do %strong.fly-out-top-item-name - #{ _('Overview') } + = _('Overview') %li.divider.fly-out-top-item = nav_link(controller: :dashboard, html_options: {class: 'home'}) do - = link_to admin_root_path, title: 'Overview' do + = link_to admin_root_path, title: _('Overview') do %span - Dashboard + = _('Dashboard') = nav_link(controller: [:admin, :projects]) do - = link_to admin_projects_path, title: 'Projects' do + = link_to admin_projects_path, title: _('Projects') do %span - Projects + = _('Projects') = nav_link(controller: :users) do - = link_to admin_users_path, title: 'Users' do + = link_to admin_users_path, title: _('Users') do %span - Users + = _('Users') = nav_link(controller: :groups) do - = link_to admin_groups_path, title: 'Groups' do + = link_to admin_groups_path, title: _('Groups') do %span - Groups + = _('Groups') = nav_link path: 'jobs#index' do - = link_to admin_jobs_path, title: 'Jobs' do + = link_to admin_jobs_path, title: _('Jobs') do %span - Jobs + = _('Jobs') = nav_link path: ['runners#index', 'runners#show'] do - = link_to admin_runners_path, title: 'Runners' do + = link_to admin_runners_path, title: _('Runners') do %span - Runners + = _('Runners') = nav_link(controller: :gitaly_servers) do = link_to admin_gitaly_servers_path, title: 'Gitaly Servers' do %span - Gitaly Servers + = _('Gitaly Servers') = nav_link path: 'cohorts#index' do - = link_to admin_cohorts_path, title: 'Cohorts' do + = link_to admin_cohorts_path, title: _('Cohorts') do %span - Cohorts + = _('Cohorts') = nav_link(controller: :conversational_development_index) do - = link_to admin_conversational_development_index_path, title: 'ConvDev Index' do + = link_to admin_conversational_development_index_path, title: _('ConvDev Index') do %span - ConvDev Index + = _('ConvDev Index') = nav_link(controller: %w(system_info background_jobs logs health_check requests_profiles)) do = link_to admin_system_info_path do .nav-icon-container = sprite_icon('monitor') %span.nav-item-name - Monitoring + = _('Monitoring') %ul.sidebar-sub-level-items = nav_link(controller: %w(system_info background_jobs logs health_check requests_profiles), html_options: { class: "fly-out-top-item" } ) do = link_to admin_system_info_path do %strong.fly-out-top-item-name - #{ _('Monitoring') } + = _('Monitoring') %li.divider.fly-out-top-item = nav_link(controller: :system_info) do - = link_to admin_system_info_path, title: 'System Info' do + = link_to admin_system_info_path, title: _('System Info') do %span - System Info + = _('System Info') = nav_link(controller: :background_jobs) do - = link_to admin_background_jobs_path, title: 'Background Jobs' do + = link_to admin_background_jobs_path, title: _('Background Jobs') do %span - Background Jobs + = _('Background Jobs') = nav_link(controller: :logs) do - = link_to admin_logs_path, title: 'Logs' do + = link_to admin_logs_path, title: _('Logs') do %span - Logs + = _('Logs') = nav_link(controller: :health_check) do - = link_to admin_health_check_path, title: 'Health Check' do + = link_to admin_health_check_path, title: _('Health Check') do %span - Health Check + = _('Health Check') = nav_link(controller: :requests_profiles) do - = link_to admin_requests_profiles_path, title: 'Requests Profiles' do + = link_to admin_requests_profiles_path, title: _('Requests Profiles') do %span - Requests Profiles + = _('Requests Profiles') = nav_link(controller: :broadcast_messages) do = link_to admin_broadcast_messages_path do .nav-icon-container = sprite_icon('messages') %span.nav-item-name - Messages + = _('Messages') %ul.sidebar-sub-level-items.is-fly-out-only = nav_link(controller: :broadcast_messages, html_options: { class: "fly-out-top-item" } ) do = link_to admin_broadcast_messages_path do %strong.fly-out-top-item-name - #{ _('Messages') } + = _('Messages') = nav_link(controller: [:hooks, :hook_logs]) do = link_to admin_hooks_path do .nav-icon-container = sprite_icon('hook') %span.nav-item-name - System Hooks + = _('System Hooks') %ul.sidebar-sub-level-items.is-fly-out-only = nav_link(controller: [:hooks, :hook_logs], html_options: { class: "fly-out-top-item" } ) do = link_to admin_hooks_path do %strong.fly-out-top-item-name - #{ _('System Hooks') } + = _('System Hooks') = nav_link(controller: :applications) do = link_to admin_applications_path do .nav-icon-container = sprite_icon('applications') %span.nav-item-name - Applications + = _('Applications') %ul.sidebar-sub-level-items.is-fly-out-only = nav_link(controller: :applications, html_options: { class: "fly-out-top-item" } ) do = link_to admin_applications_path do %strong.fly-out-top-item-name - #{ _('Applications') } + = _('Applications') = nav_link(controller: :abuse_reports) do = link_to admin_abuse_reports_path do .nav-icon-container = sprite_icon('slight-frown') %span.nav-item-name - Abuse Reports + = _('Abuse Reports') %span.badge.badge-pill.count= number_with_delimiter(AbuseReport.count(:all)) %ul.sidebar-sub-level-items.is-fly-out-only = nav_link(controller: :abuse_reports, html_options: { class: "fly-out-top-item" } ) do = link_to admin_abuse_reports_path do %strong.fly-out-top-item-name - #{ _('Abuse Reports') } + = _('Abuse Reports') %span.badge.badge-pill.count.merge_counter.js-merge-counter.fly-out-badge= number_with_delimiter(AbuseReport.count(:all)) - if akismet_enabled? @@ -145,71 +146,71 @@ .nav-icon-container = sprite_icon('spam') %span.nav-item-name - Spam Logs + = _('Spam Logs') %ul.sidebar-sub-level-items.is-fly-out-only = nav_link(controller: :spam_logs, html_options: { class: "fly-out-top-item" } ) do = link_to admin_spam_logs_path do %strong.fly-out-top-item-name - #{ _('Spam Logs') } + = _('Spam Logs') = nav_link(controller: :deploy_keys) do = link_to admin_deploy_keys_path do .nav-icon-container = sprite_icon('key') %span.nav-item-name - Deploy Keys + = _('Deploy Keys') %ul.sidebar-sub-level-items.is-fly-out-only = nav_link(controller: :deploy_keys, html_options: { class: "fly-out-top-item" } ) do = link_to admin_deploy_keys_path do %strong.fly-out-top-item-name - #{ _('Deploy Keys') } + = _('Deploy Keys') = nav_link(controller: :services) do = link_to admin_application_settings_services_path do .nav-icon-container = sprite_icon('template') %span.nav-item-name - Service Templates + = _('Service Templates') %ul.sidebar-sub-level-items.is-fly-out-only = nav_link(controller: :services, html_options: { class: "fly-out-top-item" } ) do = link_to admin_application_settings_services_path do %strong.fly-out-top-item-name - #{ _('Service Templates') } + = _('Service Templates') = nav_link(controller: :labels) do = link_to admin_labels_path do .nav-icon-container = sprite_icon('labels') %span.nav-item-name - Labels + = _('Labels') %ul.sidebar-sub-level-items.is-fly-out-only = nav_link(controller: :labels, html_options: { class: "fly-out-top-item" } ) do = link_to admin_labels_path do %strong.fly-out-top-item-name - #{ _('Labels') } + = _('Labels') = nav_link(controller: :appearances) do = link_to admin_appearances_path do .nav-icon-container = sprite_icon('appearance') %span.nav-item-name - Appearance + = _('Appearance') %ul.sidebar-sub-level-items.is-fly-out-only = nav_link(controller: :appearances, html_options: { class: "fly-out-top-item" } ) do = link_to admin_appearances_path do %strong.fly-out-top-item-name - #{ _('Appearance') } + = _('Appearance') = nav_link(controller: :application_settings) do = link_to admin_application_settings_path do .nav-icon-container = sprite_icon('settings') %span.nav-item-name - Settings + = _('Settings') %ul.sidebar-sub-level-items.is-fly-out-only = nav_link(controller: :application_settings, html_options: { class: "fly-out-top-item" } ) do = link_to admin_application_settings_path do %strong.fly-out-top-item-name - #{ _('Settings') } + = _('Settings') = render 'shared/sidebar_toggle_button' diff --git a/app/views/layouts/nav/sidebar/_group.html.haml b/app/views/layouts/nav/sidebar/_group.html.haml index 39a033337ff..0a3b5ec7eea 100644 --- a/app/views/layouts/nav/sidebar/_group.html.haml +++ b/app/views/layouts/nav/sidebar/_group.html.haml @@ -17,24 +17,24 @@ .nav-icon-container = sprite_icon('project') %span.nav-item-name - Overview + = _('Overview') %ul.sidebar-sub-level-items = nav_link(path: ['groups#show', 'groups#activity', 'groups#subgroups'], html_options: { class: "fly-out-top-item" } ) do = link_to group_path(@group) do %strong.fly-out-top-item-name - #{ _('Overview') } + = _('Overview') %li.divider.fly-out-top-item = nav_link(path: ['groups#show', 'groups#subgroups'], html_options: { class: 'home' }) do - = link_to group_path(@group), title: 'Group details' do + = link_to group_path(@group), title: _('Group details') do %span - Details + = _('Details') - if group_sidebar_link?(:activity) = nav_link(path: 'groups#activity') do - = link_to activity_group_path(@group), title: 'Activity' do + = link_to activity_group_path(@group), title: _('Activity') do %span - Activity + = _('Activity') - if group_sidebar_link?(:issues) = nav_link(path: issues_sub_menu_items) do @@ -42,21 +42,21 @@ .nav-icon-container = sprite_icon('issues') %span.nav-item-name - Issues + = _('Issues') %span.badge.badge-pill.count= number_with_delimiter(issues_count) %ul.sidebar-sub-level-items = nav_link(path: ['groups#issues', 'labels#index', 'milestones#index'], html_options: { class: "fly-out-top-item" } ) do = link_to issues_group_path(@group) do %strong.fly-out-top-item-name - #{ _('Issues') } + = _('Issues') %span.badge.badge-pill.count.issue_counter.fly-out-badge= number_with_delimiter(issues_count) %li.divider.fly-out-top-item = nav_link(path: 'groups#issues', html_options: { class: 'home' }) do - = link_to issues_group_path(@group), title: 'List' do + = link_to issues_group_path(@group), title: _('List') do %span - List + = _('List') - if group_sidebar_link?(:boards) = nav_link(path: ['boards#index', 'boards#show']) do @@ -66,15 +66,15 @@ - if group_sidebar_link?(:labels) = nav_link(path: 'labels#index') do - = link_to group_labels_path(@group), title: 'Labels' do + = link_to group_labels_path(@group), title: _('Labels') do %span - Labels + = _('Labels') - if group_sidebar_link?(:milestones) = nav_link(path: 'milestones#index') do - = link_to group_milestones_path(@group), title: 'Milestones' do + = link_to group_milestones_path(@group), title: _('Milestones') do %span - Milestones + = _('Milestones') - if group_sidebar_link?(:merge_requests) = nav_link(path: 'groups#merge_requests') do @@ -82,13 +82,13 @@ .nav-icon-container = sprite_icon('git-merge') %span.nav-item-name - Merge Requests + = _('Merge Requests') %span.badge.badge-pill.count= number_with_delimiter(merge_requests_count) %ul.sidebar-sub-level-items.is-fly-out-only = nav_link(path: 'groups#merge_requests', html_options: { class: "fly-out-top-item" } ) do = link_to merge_requests_group_path(@group) do %strong.fly-out-top-item-name - #{ _('Merge Requests') } + = _('Merge Requests') %span.badge.badge-pill.count.merge_counter.js-merge-counter.fly-out-badge= number_with_delimiter(merge_requests_count) - if group_sidebar_link?(:group_members) @@ -97,12 +97,12 @@ .nav-icon-container = sprite_icon('users') %span.nav-item-name - Members + = _('Members') %ul.sidebar-sub-level-items.is-fly-out-only = nav_link(path: 'group_members#index', html_options: { class: "fly-out-top-item" } ) do = link_to group_group_members_path(@group) do %strong.fly-out-top-item-name - #{ _('Members') } + = _('Members') - if group_sidebar_link?(:settings) = nav_link(path: group_nav_link_paths) do @@ -110,17 +110,17 @@ .nav-icon-container = sprite_icon('settings') %span.nav-item-name - Settings + = _('Settings') %ul.sidebar-sub-level-items = nav_link(path: %w[groups#projects groups#edit badges#index ci_cd#show], html_options: { class: "fly-out-top-item" } ) do = link_to edit_group_path(@group) do %strong.fly-out-top-item-name - #{ _('Settings') } + = _('Settings') %li.divider.fly-out-top-item = nav_link(path: 'groups#edit') do - = link_to edit_group_path(@group), title: 'General' do + = link_to edit_group_path(@group), title: _('General') do %span - General + = _('General') = nav_link(controller: :badges) do = link_to group_settings_badges_path(@group), title: _('Project Badges') do @@ -129,13 +129,13 @@ = nav_link(path: 'groups#projects') do - = link_to projects_group_path(@group), title: 'Projects' do + = link_to projects_group_path(@group), title: _('Projects') do %span - Projects + = _('Projects') = nav_link(controller: :ci_cd) do - = link_to group_settings_ci_cd_path(@group), title: 'CI / CD' do + = link_to group_settings_ci_cd_path(@group), title: _('CI / CD') do %span - CI / CD + = _('CI / CD') = render 'shared/sidebar_toggle_button' diff --git a/app/views/layouts/nav/sidebar/_profile.html.haml b/app/views/layouts/nav/sidebar/_profile.html.haml index 6cbd163dd41..94863a3460d 100644 --- a/app/views/layouts/nav/sidebar/_profile.html.haml +++ b/app/views/layouts/nav/sidebar/_profile.html.haml @@ -1,7 +1,7 @@ .nav-sidebar{ class: ("sidebar-collapsed-desktop" if collapsed_sidebar?) } .nav-sidebar-inner-scroll .context-header - = link_to profile_path, title: 'Profile Settings' do + = link_to profile_path, title: _('Profile Settings') do .avatar-container.s40.settings-avatar = sprite_icon('user', size: 24) .sidebar-context-title User Settings @@ -11,145 +11,145 @@ .nav-icon-container = sprite_icon('profile') %span.nav-item-name - Profile + = _('Profile') %ul.sidebar-sub-level-items.is-fly-out-only = nav_link(path: 'profiles#show', html_options: { class: "fly-out-top-item" } ) do = link_to profile_path do %strong.fly-out-top-item-name - #{ _('Profile') } + = _('Profile') = nav_link(controller: [:accounts, :two_factor_auths]) do = link_to profile_account_path do .nav-icon-container = sprite_icon('account') %span.nav-item-name - Account + = _('Account') %ul.sidebar-sub-level-items.is-fly-out-only = nav_link(controller: [:accounts, :two_factor_auths], html_options: { class: "fly-out-top-item" } ) do = link_to profile_account_path do %strong.fly-out-top-item-name - #{ _('Account') } + = _('Account') - if Gitlab::CurrentSettings.user_oauth_applications? = nav_link(controller: 'oauth/applications') do = link_to applications_profile_path do .nav-icon-container = sprite_icon('applications') %span.nav-item-name - Applications + = _('Applications') %ul.sidebar-sub-level-items.is-fly-out-only = nav_link(controller: 'oauth/applications', html_options: { class: "fly-out-top-item" } ) do = link_to applications_profile_path do %strong.fly-out-top-item-name - #{ _('Applications') } + = _('Applications') = nav_link(controller: :chat_names) do = link_to profile_chat_names_path do .nav-icon-container = sprite_icon('comment') %span.nav-item-name - Chat + = _('Chat') %ul.sidebar-sub-level-items.is-fly-out-only = nav_link(controller: :chat_names, html_options: { class: "fly-out-top-item" } ) do = link_to profile_chat_names_path do %strong.fly-out-top-item-name - #{ _('Chat') } + = _('Chat') = nav_link(controller: :personal_access_tokens) do = link_to profile_personal_access_tokens_path do .nav-icon-container = sprite_icon('token') %span.nav-item-name - Access Tokens + = _('Access Tokens') %ul.sidebar-sub-level-items.is-fly-out-only = nav_link(controller: :personal_access_tokens, html_options: { class: "fly-out-top-item" } ) do = link_to profile_personal_access_tokens_path do %strong.fly-out-top-item-name - #{ _('Access Tokens') } + = _('Access Tokens') = nav_link(controller: :emails) do = link_to profile_emails_path do .nav-icon-container = sprite_icon('mail') %span.nav-item-name - Emails + = _('Emails') %ul.sidebar-sub-level-items.is-fly-out-only = nav_link(controller: :emails, html_options: { class: "fly-out-top-item" } ) do = link_to profile_emails_path do %strong.fly-out-top-item-name - #{ _('Emails') } + = _('Emails') - if current_user.allow_password_authentication? = nav_link(controller: :passwords) do = link_to edit_profile_password_path do .nav-icon-container = sprite_icon('lock') %span.nav-item-name - Password + = _('Password') %ul.sidebar-sub-level-items.is-fly-out-only = nav_link(controller: :passwords, html_options: { class: "fly-out-top-item" } ) do = link_to edit_profile_password_path do %strong.fly-out-top-item-name - #{ _('Password') } + = _('Password') = nav_link(controller: :notifications) do = link_to profile_notifications_path do .nav-icon-container = sprite_icon('notifications') %span.nav-item-name - Notifications + = _('Notifications') %ul.sidebar-sub-level-items.is-fly-out-only = nav_link(controller: :notifications, html_options: { class: "fly-out-top-item" } ) do = link_to profile_notifications_path do %strong.fly-out-top-item-name - #{ _('Notifications') } + = _('Notifications') = nav_link(controller: :keys) do = link_to profile_keys_path do .nav-icon-container = sprite_icon('key') %span.nav-item-name - SSH Keys + = _('SSH Keys') %ul.sidebar-sub-level-items.is-fly-out-only = nav_link(controller: :keys, html_options: { class: "fly-out-top-item" } ) do = link_to profile_keys_path do %strong.fly-out-top-item-name - #{ _('SSH Keys') } + = _('SSH Keys') = nav_link(controller: :gpg_keys) do = link_to profile_gpg_keys_path do .nav-icon-container = sprite_icon('key-2') %span.nav-item-name - GPG Keys + = _('GPG Keys') %ul.sidebar-sub-level-items.is-fly-out-only = nav_link(controller: :gpg_keys, html_options: { class: "fly-out-top-item" } ) do = link_to profile_gpg_keys_path do %strong.fly-out-top-item-name - #{ _('GPG Keys') } + = _('GPG Keys') = nav_link(controller: :preferences) do = link_to profile_preferences_path do .nav-icon-container = sprite_icon('preferences') %span.nav-item-name - Preferences + = _('Preferences') %ul.sidebar-sub-level-items.is-fly-out-only = nav_link(controller: :preferences, html_options: { class: "fly-out-top-item" } ) do = link_to profile_preferences_path do %strong.fly-out-top-item-name - #{ _('Preferences') } + = _('Preferences') = nav_link(controller: :active_sessions) do = link_to profile_active_sessions_path do .nav-icon-container = sprite_icon('monitor-lines') %span.nav-item-name - Active Sessions + = _('Active Sessions') %ul.sidebar-sub-level-items.is-fly-out-only = nav_link(controller: :active_sessions, html_options: { class: "fly-out-top-item" } ) do = link_to profile_active_sessions_path do %strong.fly-out-top-item-name - #{ _('Active Sessions') } + = _('Active Sessions') = nav_link(path: 'profiles#audit_log') do = link_to audit_log_profile_path do .nav-icon-container = sprite_icon('log') %span.nav-item-name - Authentication log + = _('Authentication log') %ul.sidebar-sub-level-items.is-fly-out-only = nav_link(path: 'profiles#audit_log', html_options: { class: "fly-out-top-item" } ) do = link_to audit_log_profile_path do %strong.fly-out-top-item-name - #{ _('Authentication Log') } + = _('Authentication Log') = render 'shared/sidebar_toggle_button' diff --git a/app/views/layouts/nav/sidebar/_project.html.haml b/app/views/layouts/nav/sidebar/_project.html.haml index 33de74dbaa2..0ec61df1f0a 100644 --- a/app/views/layouts/nav/sidebar/_project.html.haml +++ b/app/views/layouts/nav/sidebar/_project.html.haml @@ -105,7 +105,7 @@ = number_with_delimiter(@project.open_issues_count(current_user)) %li.divider.fly-out-top-item = nav_link(controller: :issues, action: :index) do - = link_to project_issues_path(@project), title: 'Issues' do + = link_to project_issues_path(@project), title: _('Issues') do %span = _('List') @@ -115,14 +115,14 @@ = boards_link_text = nav_link(controller: :labels) do - = link_to project_labels_path(@project), title: 'Labels' do + = link_to project_labels_path(@project), title: _('Labels') do %span = _('Labels') = render_if_exists 'projects/sidebar/issues_service_desk' = nav_link(controller: :milestones) do - = link_to project_milestones_path(@project), title: 'Milestones', class: 'qa-milestones-link' do + = link_to project_milestones_path(@project), title: _('Milestones'), class: 'qa-milestones-link' do %span = _('Milestones') - if project_nav_tab? :external_issue_tracker @@ -172,25 +172,25 @@ %li.divider.fly-out-top-item - if project_nav_tab? :pipelines = nav_link(path: ['pipelines#index', 'pipelines#show']) do - = link_to project_pipelines_path(@project), title: 'Pipelines', class: 'shortcuts-pipelines' do + = link_to project_pipelines_path(@project), title: _('Pipelines'), class: 'shortcuts-pipelines' do %span = _('Pipelines') - if project_nav_tab? :builds = nav_link(controller: [:jobs, :artifacts]) do - = link_to project_jobs_path(@project), title: 'Jobs', class: 'shortcuts-builds' do + = link_to project_jobs_path(@project), title: _('Jobs'), class: 'shortcuts-builds' do %span = _('Jobs') - if project_nav_tab? :pipelines = nav_link(controller: :pipeline_schedules) do - = link_to pipeline_schedules_path(@project), title: 'Schedules', class: 'shortcuts-builds' do + = link_to pipeline_schedules_path(@project), title: _('Schedules'), class: 'shortcuts-builds' do %span = _('Schedules') - if @project.feature_available?(:builds, current_user) && !@project.empty_repo? = nav_link(path: 'pipelines#charts') do - = link_to charts_project_pipelines_path(@project), title: 'Charts', class: 'shortcuts-pipelines-charts' do + = link_to charts_project_pipelines_path(@project), title: _('Charts'), class: 'shortcuts-pipelines-charts' do %span = _('Charts') @@ -242,7 +242,7 @@ %p= _('Allows you to add and manage Kubernetes clusters.') %p = _('Protip:') - = link_to 'Auto DevOps', help_page_path('topics/autodevops/index.md') + = link_to _('Auto DevOps'), help_page_path('topics/autodevops/index.md') %span= _('uses Kubernetes clusters to deploy your code!') %hr %button.btn.btn-create.btn-sm.dismiss-feature-highlight{ type: 'button' } @@ -305,11 +305,11 @@ = _('Settings') %li.divider.fly-out-top-item = nav_link(path: %w[projects#edit]) do - = link_to edit_project_path(@project), title: 'General' do + = link_to edit_project_path(@project), title: _('General') do %span = _('General') = nav_link(controller: :project_members) do - = link_to project_project_members_path(@project), title: 'Members' do + = link_to project_project_members_path(@project), title: _('Members') do %span = _('Members') - if can_edit @@ -319,21 +319,21 @@ = _('Badges') - if can_edit = nav_link(controller: [:integrations, :services, :hooks, :hook_logs]) do - = link_to project_settings_integrations_path(@project), title: 'Integrations' do + = link_to project_settings_integrations_path(@project), title: _('Integrations') do %span = _('Integrations') = nav_link(controller: :repository) do - = link_to project_settings_repository_path(@project), title: 'Repository' do + = link_to project_settings_repository_path(@project), title: _('Repository') do %span = _('Repository') - if @project.feature_available?(:builds, current_user) = nav_link(controller: :ci_cd) do - = link_to project_settings_ci_cd_path(@project), title: 'CI / CD' do + = link_to project_settings_ci_cd_path(@project), title: _('CI / CD') do %span = _('CI / CD') - if @project.pages_available? = nav_link(controller: :pages) do - = link_to project_pages_path(@project), title: 'Pages' do + = link_to project_pages_path(@project), title: _('Pages') do %span = _('Pages') @@ -341,7 +341,7 @@ - else = nav_link(controller: :project_members) do - = link_to project_settings_members_path(@project), title: 'Members', class: 'shortcuts-tree' do + = link_to project_settings_members_path(@project), title: _('Members'), class: 'shortcuts-tree' do .nav-icon-container = sprite_icon('users') %span.nav-item-name @@ -356,41 +356,41 @@ -# Shortcut to Project > Activity %li.hidden - = link_to activity_project_path(@project), title: 'Activity', class: 'shortcuts-project-activity' do + = link_to activity_project_path(@project), title: _('Activity'), class: 'shortcuts-project-activity' do %span - Activity + = _('Activity') -# Shortcut to Repository > Graph (formerly, Network) - if project_nav_tab? :network %li.hidden - = link_to project_network_path(@project, current_ref), title: 'Network', class: 'shortcuts-network' do - Graph + = link_to project_network_path(@project, current_ref), title: _('Network'), class: 'shortcuts-network' do + = _('Graph') -# Shortcut to Repository > Charts (formerly, top-nav item "Graphs") - unless @project.empty_repo? %li.hidden - = link_to charts_project_graph_path(@project, current_ref), title: 'Charts', class: 'shortcuts-repository-charts' do - Charts + = link_to charts_project_graph_path(@project, current_ref), title: _('Charts'), class: 'shortcuts-repository-charts' do + = _('Charts') -# Shortcut to Issues > New Issue - if project_nav_tab?(:issues) %li.hidden = link_to new_project_issue_path(@project), class: 'shortcuts-new-issue' do - Create a new issue + = _('Create a new issue') -# Shortcut to Pipelines > Jobs - if project_nav_tab? :builds %li.hidden - = link_to project_jobs_path(@project), title: 'Jobs', class: 'shortcuts-builds' do - Jobs + = link_to project_jobs_path(@project), title: _('Jobs'), class: 'shortcuts-builds' do + = _('Jobs') -# Shortcut to commits page - if project_nav_tab? :commits %li.hidden - = link_to project_commits_path(@project), title: 'Commits', class: 'shortcuts-commits' do - Commits + = link_to project_commits_path(@project), title: _('Commits'), class: 'shortcuts-commits' do + = _('Commits') -# Shortcut to issue boards - if project_nav_tab?(:issues) %li.hidden - = link_to 'Issue Boards', project_boards_path(@project), title: 'Issue Boards', class: 'shortcuts-issue-boards' + = link_to _('Issue Boards'), project_boards_path(@project), title: _('Issue Boards'), class: 'shortcuts-issue-boards' diff --git a/app/views/layouts/notify.html.haml b/app/views/layouts/notify.html.haml index ab8b1271212..31e02f1ee19 100644 --- a/app/views/layouts/notify.html.haml +++ b/app/views/layouts/notify.html.haml @@ -14,13 +14,12 @@ %br - if @target_url - if @reply_by_email - Reply to this email directly or - #{link_to "view it on GitLab", @target_url}. + = _('Reply to this email directly or %{view_it_on_gitlab}.') % { view_it_on_gitlab: link_to(_("view it on GitLab"), @target_url) } - else - #{link_to "View it on GitLab", @target_url}. + #{link_to _("View it on GitLab"), @target_url}. %br -# Don't link the host in the line below, one link in the email is easier to quickly click than two. - You're receiving this email because #{notification_reason_text(@reason)}. + = _("You're receiving this email because %{reason}.") % { reason: notification_reason_text(@reason) } If you'd like to receive fewer emails, you can - if @labels_url adjust your #{link_to 'label subscriptions', @labels_url}. diff --git a/app/views/layouts/profile.html.haml b/app/views/layouts/profile.html.haml index 67aa05b655c..7aca64663e0 100644 --- a/app/views/layouts/profile.html.haml +++ b/app/views/layouts/profile.html.haml @@ -1,5 +1,5 @@ -- page_title "User Settings" -- header_title "User Settings", profile_path unless header_title +- page_title _("User Settings") +- header_title _("User Settings"), profile_path unless header_title - sidebar "dashboard" - nav "profile" - @left_sidebar = true diff --git a/app/views/layouts/project_settings.html.haml b/app/views/layouts/project_settings.html.haml index 4bc94bd132d..93214c2a674 100644 --- a/app/views/layouts/project_settings.html.haml +++ b/app/views/layouts/project_settings.html.haml @@ -1,4 +1,4 @@ -- page_title "Settings" +- page_title _("Settings") - nav "project" = render template: "layouts/project" diff --git a/app/views/layouts/search.html.haml b/app/views/layouts/search.html.haml index fd4c7ad21a7..dd4b9e45207 100644 --- a/app/views/layouts/search.html.haml +++ b/app/views/layouts/search.html.haml @@ -1,4 +1,4 @@ -- page_title "Search" -- header_title "Search", search_path +- page_title _("Search") +- header_title _("Search"), search_path = render template: "layouts/application" diff --git a/app/views/layouts/snippets.html.haml b/app/views/layouts/snippets.html.haml index 849075a0ba5..6418500d5d1 100644 --- a/app/views/layouts/snippets.html.haml +++ b/app/views/layouts/snippets.html.haml @@ -1,4 +1,4 @@ -- header_title "Snippets", snippets_path +- header_title _("Snippets"), snippets_path - content_for :page_specific_javascripts do - if @snippet && current_user diff --git a/app/views/profiles/show.html.haml b/app/views/profiles/show.html.haml index 507cd5dcc12..a4835584b50 100644 --- a/app/views/profiles/show.html.haml +++ b/app/views/profiles/show.html.haml @@ -69,6 +69,12 @@ = f.text_field :location = f.text_field :organization = f.text_area :bio, rows: 4, maxlength: 250, help: 'Tell us about yourself in fewer than 250 characters.' + %hr + %h5 Private profile + - private_profile_label = capture do + Don't display activity-related personal information on your profile + = link_to icon('question-circle'), help_page_path('user/profile/index.md', anchor: 'private-profile') + = f.check_box :private_profile, label: private_profile_label .prepend-top-default.append-bottom-default = f.submit 'Update profile settings', class: 'btn btn-success' = link_to 'Cancel', user_path(current_user), class: 'btn btn-cancel' diff --git a/app/views/projects/blame/show.html.haml b/app/views/projects/blame/show.html.haml index e90916e340d..ef6f5c76de6 100644 --- a/app/views/projects/blame/show.html.haml +++ b/app/views/projects/blame/show.html.haml @@ -18,7 +18,7 @@ - commit = blame_group[:commit] %td.blame-commit{ class: age_map_class(commit.committed_date, project_duration) } .commit - = author_avatar(commit, size: 36) + = author_avatar(commit, size: 36, has_tooltip: false) .commit-row-title %span.item-title.str-truncated-100 = link_to_markdown commit.title, project_commit_path(@project, commit.id), class: "cdark", title: commit.title diff --git a/app/views/projects/blob/show.html.haml b/app/views/projects/blob/show.html.haml index efb8175398b..5edab38bd64 100644 --- a/app/views/projects/blob/show.html.haml +++ b/app/views/projects/blob/show.html.haml @@ -3,6 +3,8 @@ - page_title @blob.path, @ref +.js-signature-container{ data: { 'signatures-path': namespace_project_signatures_path } } + %div{ class: container_class } = render 'projects/last_push' diff --git a/app/views/projects/buttons/_star.html.haml b/app/views/projects/buttons/_star.html.haml index d8b4266143e..a2dc2730ecc 100644 --- a/app/views/projects/buttons/_star.html.haml +++ b/app/views/projects/buttons/_star.html.haml @@ -1,5 +1,5 @@ - if current_user - %button.btn.btn-default.star-btn.toggle-star{ type: "button", data: { endpoint: toggle_star_project_path(@project, :json) } } + %button.btn.btn-default.star-btn.toggle-star{ type: "button", data: { endpoint: toggle_star_project_path(@project, :json) } }> - if current_user.starred?(@project) = sprite_icon('star') %span.starred= _('Unstar') diff --git a/app/views/projects/commit/_commit_box.html.haml b/app/views/projects/commit/_commit_box.html.haml index 886dd73c33b..78522393d4b 100644 --- a/app/views/projects/commit/_commit_box.html.haml +++ b/app/views/projects/commit/_commit_box.html.haml @@ -10,7 +10,7 @@ %span.d-none.d-sm-inline authored #{time_ago_with_tooltip(@commit.authored_date)} %span= s_('ByAuthor|by') - = author_avatar(@commit, size: 24) + = author_avatar(@commit, size: 24, has_tooltip: false) %strong = commit_author_link(@commit, avatar: true, size: 24) - if @commit.different_committer? diff --git a/app/views/projects/commits/_commit.html.haml b/app/views/projects/commits/_commit.html.haml index 90e55fd0fb0..feaf44e8c0a 100644 --- a/app/views/projects/commits/_commit.html.haml +++ b/app/views/projects/commits/_commit.html.haml @@ -19,7 +19,7 @@ %li.commit.flex-row.js-toggle-container{ id: "commit-#{commit.short_id}" } .avatar-cell.d-none.d-sm-block - = author_avatar(commit, size: 36) + = author_avatar(commit, size: 36, has_tooltip: false) .commit-detail.flex-list .commit-content.qa-commit-content diff --git a/app/views/projects/pipelines/_info.html.haml b/app/views/projects/pipelines/_info.html.haml index 04131a90a57..bc247460d28 100644 --- a/app/views/projects/pipelines/_info.html.haml +++ b/app/views/projects/pipelines/_info.html.haml @@ -33,3 +33,5 @@ %span.js-details-content.hide = link_to @pipeline.sha, project_commit_path(@project, @pipeline.sha), class: "commit-sha commit-hash-full" = clipboard_button(text: @pipeline.sha, title: "Copy commit SHA to clipboard") + + = render_if_exists "projects/pipelines/info_extension", pipeline: @pipeline diff --git a/app/views/projects/pipelines/_with_tabs.html.haml b/app/views/projects/pipelines/_with_tabs.html.haml index 951f80b378d..c63ff070f70 100644 --- a/app/views/projects/pipelines/_with_tabs.html.haml +++ b/app/views/projects/pipelines/_with_tabs.html.haml @@ -12,6 +12,7 @@ = link_to failures_project_pipeline_path(@project, @pipeline), data: { target: '#js-tab-failures', action: 'failures', toggle: 'tab' }, class: 'failures-tab' do = _("Failed Jobs") %span.badge.badge-pill.js-failures-counter= @pipeline.failed_builds.count + = render_if_exists "projects/pipelines/tabs_holder", pipeline: @pipeline, project: @project .tab-content #js-tab-pipeline.tab-pane @@ -75,4 +76,4 @@ %pre.build-trace.build-trace-rounded %code.bash.js-build-output = build_summary(build) - + = render_if_exists "projects/pipelines/tabs_content", pipeline: @pipeline, project: @project diff --git a/app/views/projects/pipelines/new.html.haml b/app/views/projects/pipelines/new.html.haml index 956f8fef6b8..c13e3194340 100644 --- a/app/views/projects/pipelines/new.html.haml +++ b/app/views/projects/pipelines/new.html.haml @@ -10,7 +10,7 @@ = form_errors(@pipeline) .form-group.row .col-sm-12 - = f.label :ref, s_('Pipeline|Create for') + = f.label :ref, s_('Pipeline|Create for'), class: 'col-form-label' = hidden_field_tag 'pipeline[ref]', params[:ref] || @project.default_branch = dropdown_tag(params[:ref] || @project.default_branch, options: { toggle_class: 'js-branch-select wide git-revision-dropdown-toggle', diff --git a/app/views/projects/services/prometheus/_show.html.haml b/app/views/projects/services/prometheus/_show.html.haml index 9741b783db3..1d0b0265bb7 100644 --- a/app/views/projects/services/prometheus/_show.html.haml +++ b/app/views/projects/services/prometheus/_show.html.haml @@ -7,4 +7,4 @@ = link_to s_('PrometheusService|More information'), help_page_path('user/project/integrations/prometheus_library/metrics'), target: '_blank', rel: "noopener noreferrer" .col-lg-9 - = render_if_exists 'projects/services/prometheus/metrics', project: @project + = render 'projects/services/prometheus/metrics', project: @project diff --git a/app/views/projects/show.html.haml b/app/views/projects/show.html.haml index e28accd5b43..803ecca48f7 100644 --- a/app/views/projects/show.html.haml +++ b/app/views/projects/show.html.haml @@ -8,6 +8,10 @@ = render partial: 'flash_messages', locals: { project: @project } +- if @project.repository_exists? && !@project.empty_repo? + - signatures_path = namespace_project_signatures_path(project_id: @project.path, id: @project.default_branch) + .js-signature-container{ data: { 'signatures-path': signatures_path } } + %div{ class: [container_class, ("limit-container-width" unless fluid_layout)] } = render "projects/last_push" diff --git a/app/views/projects/tree/show.html.haml b/app/views/projects/tree/show.html.haml index 3b4057e56d0..ace8120eeff 100644 --- a/app/views/projects/tree/show.html.haml +++ b/app/views/projects/tree/show.html.haml @@ -1,11 +1,14 @@ - @no_container = true - breadcrumb_title _("Repository") - @content_class = "limit-container-width" unless fluid_layout +- signatures_path = namespace_project_signatures_path(namespace_id: @project.namespace.path, project_id: @project.path, id: @ref) - page_title @path.presence || _("Files"), @ref = content_for :meta_tags do = auto_discovery_link_tag(:atom, project_commits_url(@project, @ref, rss_url_options), title: "#{@project.name}:#{@ref} commits") +.js-signature-container{ data: { 'signatures-path': signatures_path } } + %div{ class: [(container_class), ("limit-container-width" unless fluid_layout)] } = render 'projects/last_push' = render 'projects/files', commit: @last_commit, project: @project, ref: @ref, content_url: project_tree_path(@project, @id) diff --git a/app/views/shared/notes/_notes_with_form.html.haml b/app/views/shared/notes/_notes_with_form.html.haml index e0832fd9136..9dd1c24fdfa 100644 --- a/app/views/shared/notes/_notes_with_form.html.haml +++ b/app/views/shared/notes/_notes_with_form.html.haml @@ -13,7 +13,7 @@ .flash-container.timeline-content .timeline-icon.d-none.d-sm-none.d-md-block - %a.author_link{ href: user_path(current_user) } + %a.author-link{ href: user_path(current_user) } = image_tag avatar_icon_for_user(current_user), alt: current_user.to_reference, class: 'avatar s40' .timeline-content.timeline-content-form = render "shared/notes/form", view: diff_view, supports_autocomplete: autocomplete diff --git a/app/views/sherlock/queries/_general.html.haml b/app/views/sherlock/queries/_general.html.haml index 37747faed62..ddc089b0bd7 100644 --- a/app/views/sherlock/queries/_general.html.haml +++ b/app/views/sherlock/queries/_general.html.haml @@ -27,7 +27,7 @@ .card-header .float-right %button.js-clipboard-trigger.btn.btn-sm{ title: t('sherlock.copy_to_clipboard'), type: :button } - %i.fa.fa-clipboard + = sprite_icon('duplicate') %pre.hidden = @query.formatted_query %strong @@ -42,7 +42,7 @@ .card-header .float-right %button.js-clipboard-trigger.btn.btn-sm{ title: t('sherlock.copy_to_clipboard'), type: :button } - %i.fa.fa-clipboard + = sprite_icon('duplicate') %pre.hidden = @query.explain %strong diff --git a/app/views/users/show.html.haml b/app/views/users/show.html.haml index b2ec7166832..8d9e86d02c4 100644 --- a/app/views/users/show.html.haml +++ b/app/views/users/show.html.haml @@ -23,8 +23,9 @@ = link_to new_abuse_report_path(user_id: @user.id, ref_url: request.referrer), class: 'btn', title: 'Report abuse', data: { toggle: 'tooltip', placement: 'bottom', container: 'body' } do = icon('exclamation-circle') - = link_to user_path(@user, rss_url_options), class: 'btn btn-default has-tooltip', title: 'Subscribe', 'aria-label': 'Subscribe' do - = icon('rss') + - if can?(current_user, :read_user_profile, @user) + = link_to user_path(@user, rss_url_options), class: 'btn btn-default has-tooltip', title: 'Subscribe', 'aria-label': 'Subscribe' do + = icon('rss') - if current_user && current_user.admin? = link_to [:admin, @user], class: 'btn btn-default', title: 'View user in admin area', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do @@ -40,10 +41,12 @@ = @user.name .cover-desc.member-date - %span.middle-dot-divider - @#{@user.username} - %span.middle-dot-divider - Member since #{@user.created_at.to_date.to_s(:long)} + %p + %span.middle-dot-divider + @#{@user.username} + - if can?(current_user, :read_user_profile, @user) + %span.middle-dot-divider + Member since #{@user.created_at.to_date.to_s(:long)} .cover-desc - unless @user.public_email.blank? @@ -78,30 +81,31 @@ %p.profile-user-bio = @user.bio - .scrolling-tabs-container - .fade-left= icon('angle-left') - .fade-right= icon('angle-right') - %ul.nav-links.user-profile-nav.scrolling-tabs.nav.nav-tabs - - if profile_tab?(:activity) - %li.js-activity-tab - = link_to user_path, data: { target: 'div#activity', action: 'activity', toggle: 'tab' } do - Activity - - if profile_tab?(:groups) - %li.js-groups-tab - = link_to user_groups_path, data: { target: 'div#groups', action: 'groups', toggle: 'tab', endpoint: user_groups_path(format: :json) } do - Groups - - if profile_tab?(:contributed) - %li.js-contributed-tab - = link_to user_contributed_projects_path, data: { target: 'div#contributed', action: 'contributed', toggle: 'tab', endpoint: user_contributed_projects_path(format: :json) } do - Contributed projects - - if profile_tab?(:projects) - %li.js-projects-tab - = link_to user_projects_path, data: { target: 'div#projects', action: 'projects', toggle: 'tab', endpoint: user_projects_path(format: :json) } do - Personal projects - - if profile_tab?(:snippets) - %li.js-snippets-tab - = link_to user_snippets_path, data: { target: 'div#snippets', action: 'snippets', toggle: 'tab', endpoint: user_snippets_path(format: :json) } do - Snippets + - unless profile_tabs.empty? + .scrolling-tabs-container + .fade-left= icon('angle-left') + .fade-right= icon('angle-right') + %ul.nav-links.user-profile-nav.scrolling-tabs.nav.nav-tabs + - if profile_tab?(:activity) + %li.js-activity-tab + = link_to user_path, data: { target: 'div#activity', action: 'activity', toggle: 'tab' } do + Activity + - if profile_tab?(:groups) + %li.js-groups-tab + = link_to user_groups_path, data: { target: 'div#groups', action: 'groups', toggle: 'tab', endpoint: user_groups_path(format: :json) } do + Groups + - if profile_tab?(:contributed) + %li.js-contributed-tab + = link_to user_contributed_projects_path, data: { target: 'div#contributed', action: 'contributed', toggle: 'tab', endpoint: user_contributed_projects_path(format: :json) } do + Contributed projects + - if profile_tab?(:projects) + %li.js-projects-tab + = link_to user_projects_path, data: { target: 'div#projects', action: 'projects', toggle: 'tab', endpoint: user_projects_path(format: :json) } do + Personal projects + - if profile_tab?(:snippets) + %li.js-snippets-tab + = link_to user_snippets_path, data: { target: 'div#snippets', action: 'snippets', toggle: 'tab', endpoint: user_snippets_path(format: :json) } do + Snippets %div{ class: container_class } .tab-content @@ -137,3 +141,13 @@ .loading-status = spinner + + - if profile_tabs.empty? + .row + .col-12 + .svg-content + = image_tag 'illustrations/profile_private_mode.svg' + .col-12.text-center + .text-content + %h4 + This user has a private profile diff --git a/app/workers/concerns/each_shard_worker.rb b/app/workers/concerns/each_shard_worker.rb index d0a728fb495..00f589f957e 100644 --- a/app/workers/concerns/each_shard_worker.rb +++ b/app/workers/concerns/each_shard_worker.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module EachShardWorker extend ActiveSupport::Concern include ::Gitlab::Utils::StrongMemoize diff --git a/app/workers/delete_diff_files_worker.rb b/app/workers/delete_diff_files_worker.rb index bb8fbb9c373..0874a0b75e8 100644 --- a/app/workers/delete_diff_files_worker.rb +++ b/app/workers/delete_diff_files_worker.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class DeleteDiffFilesWorker include ApplicationWorker diff --git a/app/workers/repository_check/dispatch_worker.rb b/app/workers/repository_check/dispatch_worker.rb index 96634f09a15..0a7d9a14c6a 100644 --- a/app/workers/repository_check/dispatch_worker.rb +++ b/app/workers/repository_check/dispatch_worker.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module RepositoryCheck class DispatchWorker include ApplicationWorker |