diff options
Diffstat (limited to 'app')
59 files changed, 275 insertions, 321 deletions
diff --git a/app/assets/images/new_nav.png b/app/assets/images/new_nav.png Binary files differindex 8879d26d341..f98ca15d787 100644 --- a/app/assets/images/new_nav.png +++ b/app/assets/images/new_nav.png diff --git a/app/assets/javascripts/blob/notebook/index.js b/app/assets/javascripts/blob/notebook/index.js index 36fe8a7184f..27312d718b0 100644 --- a/app/assets/javascripts/blob/notebook/index.js +++ b/app/assets/javascripts/blob/notebook/index.js @@ -51,8 +51,9 @@ export default () => { methods: { loadFile() { this.$http.get(el.dataset.endpoint) + .then(response => response.json()) .then((res) => { - this.json = res.json(); + this.json = res; this.loading = false; }) .catch((e) => { diff --git a/app/assets/javascripts/boards/boards_bundle.js b/app/assets/javascripts/boards/boards_bundle.js index b94009ee76b..88b054b76e6 100644 --- a/app/assets/javascripts/boards/boards_bundle.js +++ b/app/assets/javascripts/boards/boards_bundle.js @@ -81,8 +81,9 @@ $(() => { mounted () { Store.disabled = this.disabled; gl.boardService.all() + .then(response => response.json()) .then((resp) => { - resp.json().forEach((board) => { + resp.forEach((board) => { const list = Store.addList(board, this.defaultAvatar); if (list.type === 'closed') { @@ -97,7 +98,8 @@ $(() => { Store.addBlankState(); this.loading = false; - }).catch(() => new Flash('An error occurred. Please try again.')); + }) + .catch(() => new Flash('An error occurred. Please try again.')); }, methods: { updateTokens() { diff --git a/app/assets/javascripts/boards/components/board_blank_state.js b/app/assets/javascripts/boards/components/board_blank_state.js index 870e115bd1a..e7f16899362 100644 --- a/app/assets/javascripts/boards/components/board_blank_state.js +++ b/app/assets/javascripts/boards/components/board_blank_state.js @@ -64,8 +64,9 @@ export default { // Save the labels gl.boardService.generateDefaultLists() - .then((resp) => { - resp.json().forEach((listObj) => { + .then(resp => resp.json()) + .then((data) => { + data.forEach((listObj) => { const list = Store.findList('title', listObj.title); list.id = listObj.id; diff --git a/app/assets/javascripts/boards/components/modal/index.js b/app/assets/javascripts/boards/components/modal/index.js index 6356c266ee2..1d36519c75c 100644 --- a/app/assets/javascripts/boards/components/modal/index.js +++ b/app/assets/javascripts/boards/components/modal/index.js @@ -88,9 +88,9 @@ gl.issueBoards.IssuesModal = Vue.extend({ return gl.boardService.getBacklog(queryData(this.filter.path, { page: this.page, per: this.perPage, - })).then((res) => { - const data = res.json(); - + })) + .then(resp => resp.json()) + .then((data) => { if (clearIssues) { this.issues = []; } diff --git a/app/assets/javascripts/boards/models/list.js b/app/assets/javascripts/boards/models/list.js index b4b09b3876e..08f7c5ddcd2 100644 --- a/app/assets/javascripts/boards/models/list.js +++ b/app/assets/javascripts/boards/models/list.js @@ -40,9 +40,8 @@ class List { save () { return gl.boardService.createList(this.label.id) - .then((resp) => { - const data = resp.json(); - + .then(resp => resp.json()) + .then((data) => { this.id = data.id; this.type = data.list_type; this.position = data.position; @@ -91,8 +90,8 @@ class List { } return gl.boardService.getIssuesForList(this.id, data) - .then((resp) => { - const data = resp.json(); + .then(resp => resp.json()) + .then((data) => { this.loading = false; this.issuesSize = data.size; @@ -109,8 +108,8 @@ class List { this.issuesSize += 1; return gl.boardService.newIssue(this.id, issue) - .then((resp) => { - const data = resp.json(); + .then(resp => resp.json()) + .then((data) => { issue.id = data.iid; if (this.issuesSize > 1) { diff --git a/app/assets/javascripts/boards/services/board_service.js b/app/assets/javascripts/boards/services/board_service.js index db9bced2f89..3742507b236 100644 --- a/app/assets/javascripts/boards/services/board_service.js +++ b/app/assets/javascripts/boards/services/board_service.js @@ -23,11 +23,6 @@ class BoardService { url: bulkUpdatePath, }, }); - - Vue.http.interceptors.push((request, next) => { - request.headers['X-CSRF-Token'] = $.rails.csrfToken(); - next(); - }); } all () { diff --git a/app/assets/javascripts/commit/pipelines/pipelines_table.vue b/app/assets/javascripts/commit/pipelines/pipelines_table.vue index 3c77f14d533..6d31b78b36d 100644 --- a/app/assets/javascripts/commit/pipelines/pipelines_table.vue +++ b/app/assets/javascripts/commit/pipelines/pipelines_table.vue @@ -51,11 +51,11 @@ }, methods: { successCallback(resp) { - const response = resp.json(); - - // depending of the endpoint the response can either bring a `pipelines` key or not. - const pipelines = response.pipelines || response; - this.setCommonData(pipelines); + return resp.json().then((response) => { + // depending of the endpoint the response can either bring a `pipelines` key or not. + const pipelines = response.pipelines || response; + this.setCommonData(pipelines); + }); }, }, }; diff --git a/app/assets/javascripts/diff_notes/components/resolve_btn.js b/app/assets/javascripts/diff_notes/components/resolve_btn.js index 9d51fb53eb2..efb6ced9f46 100644 --- a/app/assets/javascripts/diff_notes/components/resolve_btn.js +++ b/app/assets/javascripts/diff_notes/components/resolve_btn.js @@ -1,4 +1,4 @@ -/* eslint-disable comma-dangle, object-shorthand, func-names, quote-props, no-else-return, camelcase, no-new, max-len */ +/* eslint-disable comma-dangle, object-shorthand, func-names, quote-props, no-else-return, camelcase, max-len */ /* global CommentsStore */ /* global ResolveService */ /* global Flash */ @@ -64,8 +64,6 @@ const ResolveBtn = Vue.extend({ }); }, resolve: function () { - const errorFlashMsg = 'An error occurred when trying to resolve a comment. Please try again.'; - if (!this.canResolve) return; let promise; @@ -79,24 +77,20 @@ const ResolveBtn = Vue.extend({ .resolve(this.noteId); } - promise.then((response) => { - this.loading = false; + promise + .then(resp => resp.json()) + .then((data) => { + this.loading = false; - if (response.status === 200) { - const data = response.json(); const resolved_by = data ? data.resolved_by : null; CommentsStore.update(this.discussionId, this.noteId, !this.isResolved, resolved_by); this.discussion.updateHeadline(data); gl.mrWidget.checkStatus(); - } else { - new Flash(errorFlashMsg); - } - this.updateTooltip(); - }).catch(() => { - new Flash(errorFlashMsg); - }); + this.updateTooltip(); + }) + .catch(() => new Flash('An error occurred when trying to resolve a comment. Please try again.')); } }, mounted: function () { diff --git a/app/assets/javascripts/diff_notes/services/resolve.js b/app/assets/javascripts/diff_notes/services/resolve.js index 807ab11d292..2f063f6fe1f 100644 --- a/app/assets/javascripts/diff_notes/services/resolve.js +++ b/app/assets/javascripts/diff_notes/services/resolve.js @@ -1,4 +1,3 @@ -/* eslint-disable class-methods-use-this, one-var, camelcase, no-new, comma-dangle, no-param-reassign, max-len */ /* global Flash */ /* global CommentsStore */ @@ -32,27 +31,22 @@ class ResolveServiceClass { promise = this.resolveAll(mergeRequestId, discussionId); } - promise.then((response) => { - discussion.loading = false; - - if (response.status === 200) { - const data = response.json(); - const resolved_by = data ? data.resolved_by : null; + promise + .then(resp => resp.json()) + .then((data) => { + discussion.loading = false; + const resolvedBy = data ? data.resolved_by : null; if (isResolved) { discussion.unResolveAllNotes(); } else { - discussion.resolveAllNotes(resolved_by); + discussion.resolveAllNotes(resolvedBy); } gl.mrWidget.checkStatus(); discussion.updateHeadline(data); - } else { - throw new Error('An error occurred when trying to resolve discussion.'); - } - }).catch(() => { - new Flash('An error occurred when trying to resolve a discussion. Please try again.'); - }); + }) + .catch(() => new Flash('An error occurred when trying to resolve a discussion. Please try again.')); } resolveAll(mergeRequestId, discussionId) { @@ -62,7 +56,7 @@ class ResolveServiceClass { return this.discussionResource.save({ mergeRequestId, - discussionId + discussionId, }, {}); } @@ -73,7 +67,7 @@ class ResolveServiceClass { return this.discussionResource.delete({ mergeRequestId, - discussionId + discussionId, }, {}); } } diff --git a/app/assets/javascripts/environments/mixins/environments_mixin.js b/app/assets/javascripts/environments/mixins/environments_mixin.js index 25b24fbd6dc..8f4066e3a6e 100644 --- a/app/assets/javascripts/environments/mixins/environments_mixin.js +++ b/app/assets/javascripts/environments/mixins/environments_mixin.js @@ -1,17 +1,15 @@ export default { methods: { saveData(resp) { - const response = { - headers: resp.headers, - body: resp.json(), - }; + const headers = resp.headers; + return resp.json().then((response) => { + this.isLoading = false; - this.isLoading = false; - - this.store.storeAvailableCount(response.body.available_count); - this.store.storeStoppedCount(response.body.stopped_count); - this.store.storeEnvironments(response.body.environments); - this.store.setPagination(response.headers); + this.store.storeAvailableCount(response.available_count); + this.store.storeStoppedCount(response.stopped_count); + this.store.storeEnvironments(response.environments); + this.store.setPagination(headers); + }); }, }, }; diff --git a/app/assets/javascripts/groups/index.js b/app/assets/javascripts/groups/index.js index ff601db2aa6..00e1bd94c9c 100644 --- a/app/assets/javascripts/groups/index.js +++ b/app/assets/javascripts/groups/index.js @@ -99,8 +99,10 @@ document.addEventListener('DOMContentLoaded', () => { page: currentPath, }, document.title, currentPath); - this.updateGroups(response.json()); - this.updatePagination(response.headers); + return response.json().then((data) => { + this.updateGroups(data); + this.updatePagination(response.headers); + }); }) .catch(this.handleErrorResponse); }, @@ -114,18 +116,19 @@ document.addEventListener('DOMContentLoaded', () => { }, leaveGroup(group, collection) { this.service.leaveGroup(group.leavePath) + .then(resp => resp.json()) .then((response) => { $.scrollTo(0); this.store.removeGroup(group, collection); // eslint-disable-next-line no-new - new Flash(response.json().notice, 'notice'); + new Flash(response.notice, 'notice'); }) - .catch((response) => { + .catch((error) => { let message = 'An error occurred. Please try again.'; - if (response.status === 403) { + if (error.status === 403) { message = 'Failed to leave the group. Please make sure you are not the only owner'; } diff --git a/app/assets/javascripts/issue_show/components/app.vue b/app/assets/javascripts/issue_show/components/app.vue index 3d5fb7f441c..efae112923d 100644 --- a/app/assets/javascripts/issue_show/components/app.vue +++ b/app/assets/javascripts/issue_show/components/app.vue @@ -202,10 +202,7 @@ export default { this.poll = new Poll({ resource: this.service, method: 'getData', - successCallback: (res) => { - const data = res.json(); - this.store.updateState(data); - }, + successCallback: res => res.json().then(data => this.store.updateState(data)), errorCallback(err) { throw new Error(err); }, diff --git a/app/assets/javascripts/jobs/job_details_mediator.js b/app/assets/javascripts/jobs/job_details_mediator.js index 063c52fac74..cc014b815c4 100644 --- a/app/assets/javascripts/jobs/job_details_mediator.js +++ b/app/assets/javascripts/jobs/job_details_mediator.js @@ -54,9 +54,8 @@ export default class JobMediator { } successCallback(response) { - const data = response.json(); this.state.isLoading = false; - this.store.storeJob(data); + return response.json().then(data => this.store.storeJob(data)); } errorCallback() { diff --git a/app/assets/javascripts/notes.js b/app/assets/javascripts/notes.js index 1a68c5bca00..b2c503d1656 100644 --- a/app/assets/javascripts/notes.js +++ b/app/assets/javascripts/notes.js @@ -1270,7 +1270,7 @@ export default class Notes { <div class="timeline-entry-inner"> <div class="timeline-icon"> <a href="/${currentUsername}"> - <img class="avatar s40" src="${currentUserAvatar}"> + <img class="avatar s40" src="${currentUserAvatar}" /> </a> </div> <div class="timeline-content ${discussionClass}"> diff --git a/app/assets/javascripts/pipelines/components/pipelines.vue b/app/assets/javascripts/pipelines/components/pipelines.vue index 01ae07aad65..5df317a76bf 100644 --- a/app/assets/javascripts/pipelines/components/pipelines.vue +++ b/app/assets/javascripts/pipelines/components/pipelines.vue @@ -129,14 +129,11 @@ }, successCallback(resp) { - const response = { - headers: resp.headers, - body: resp.json(), - }; - - this.store.storeCount(response.body.count); - this.store.storePagination(response.headers); - this.setCommonData(response.body.pipelines); + return resp.json().then((response) => { + this.store.storeCount(response.count); + this.store.storePagination(resp.headers); + this.setCommonData(response.pipelines); + }); }, }, }; diff --git a/app/assets/javascripts/pipelines/components/stage.vue b/app/assets/javascripts/pipelines/components/stage.vue index 87b2725a045..a4a27247406 100644 --- a/app/assets/javascripts/pipelines/components/stage.vue +++ b/app/assets/javascripts/pipelines/components/stage.vue @@ -73,8 +73,9 @@ export default { fetchJobs() { this.$http.get(this.stage.dropdown_path) - .then((response) => { - this.dropdownContent = response.json().html; + .then(response => response.json()) + .then((data) => { + this.dropdownContent = data.html; this.isLoading = false; }) .catch(() => { diff --git a/app/assets/javascripts/pipelines/pipeline_details_mediatior.js b/app/assets/javascripts/pipelines/pipeline_details_mediatior.js index 82537ea06f5..385e7430a7d 100644 --- a/app/assets/javascripts/pipelines/pipeline_details_mediatior.js +++ b/app/assets/javascripts/pipelines/pipeline_details_mediatior.js @@ -40,10 +40,10 @@ export default class pipelinesMediator { } successCallback(response) { - const data = response.json(); - - this.state.isLoading = false; - this.store.storePipeline(data); + return response.json().then((data) => { + this.state.isLoading = false; + this.store.storePipeline(data); + }); } errorCallback() { diff --git a/app/assets/javascripts/sidebar/sidebar_mediator.js b/app/assets/javascripts/sidebar/sidebar_mediator.js index 5ccfb4ee9c1..721e92221cf 100644 --- a/app/assets/javascripts/sidebar/sidebar_mediator.js +++ b/app/assets/javascripts/sidebar/sidebar_mediator.js @@ -28,8 +28,8 @@ export default class SidebarMediator { fetch() { this.service.get() - .then((response) => { - const data = response.json(); + .then(response => response.json()) + .then((data) => { this.store.setAssigneeData(data); this.store.setTimeTrackingData(data); }) diff --git a/app/assets/javascripts/vue_shared/components/markdown/field.vue b/app/assets/javascripts/vue_shared/components/markdown/field.vue index 8303c556f64..4e10bbc7408 100644 --- a/app/assets/javascripts/vue_shared/components/markdown/field.vue +++ b/app/assets/javascripts/vue_shared/components/markdown/field.vue @@ -44,9 +44,8 @@ text: this.$slots.textarea[0].elm.value, }, ) - .then((res) => { - const data = res.json(); - + .then(resp => resp.json()) + .then((data) => { this.markdownPreviewLoading = false; this.markdownPreview = data.body; diff --git a/app/assets/javascripts/vue_shared/vue_resource_interceptor.js b/app/assets/javascripts/vue_shared/vue_resource_interceptor.js index 740930dce5b..7f8e514fda1 100644 --- a/app/assets/javascripts/vue_shared/vue_resource_interceptor.js +++ b/app/assets/javascripts/vue_shared/vue_resource_interceptor.js @@ -14,11 +14,22 @@ Vue.http.interceptors.push((request, next) => { }); }); -// Inject CSRF token so we don't break any tests. +// Inject CSRF token and parse headers. +// New Vue Resource version uses Headers, we are expecting a plain object to render pagination +// and polling. Vue.http.interceptors.push((request, next) => { if ($.rails) { - // eslint-disable-next-line no-param-reassign - request.headers['X-CSRF-Token'] = $.rails.csrfToken(); + request.headers.set('X-CSRF-Token', $.rails.csrfToken()); } - next(); + + next((response) => { + // Headers object has a `forEach` property that iterates through all values. + const headers = {}; + + response.headers.forEach((value, key) => { + headers[key] = value; + }); + // eslint-disable-next-line no-param-reassign + response.headers = headers; + }); }); diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 83a8eeaafde..0665622fe4a 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -42,4 +42,4 @@ /* * Styles for JS behaviors. */ -@import "behaviors.scss"; +@import "behaviors"; diff --git a/app/assets/stylesheets/framework.scss b/app/assets/stylesheets/framework.scss index 9dc9f9a9068..6ce331a9129 100644 --- a/app/assets/stylesheets/framework.scss +++ b/app/assets/stylesheets/framework.scss @@ -4,49 +4,49 @@ @import 'framework/tw_bootstrap'; @import "framework/layout"; -@import "framework/animations.scss"; -@import "framework/avatar.scss"; -@import "framework/asciidoctor.scss"; -@import "framework/blocks.scss"; -@import "framework/buttons.scss"; -@import "framework/badges.scss"; -@import "framework/calendar.scss"; -@import "framework/callout.scss"; -@import "framework/common.scss"; -@import "framework/dropdowns.scss"; -@import "framework/files.scss"; -@import "framework/filters.scss"; -@import "framework/flash.scss"; -@import "framework/forms.scss"; -@import "framework/gfm.scss"; -@import "framework/header.scss"; -@import "framework/highlight.scss"; -@import "framework/issue_box.scss"; -@import "framework/jquery.scss"; -@import "framework/lists.scss"; -@import "framework/logo.scss"; -@import "framework/markdown_area.scss"; -@import "framework/mobile.scss"; -@import "framework/modal.scss"; -@import "framework/nav.scss"; -@import "framework/pagination.scss"; -@import "framework/panels.scss"; -@import "framework/selects.scss"; -@import "framework/sidebar.scss"; -@import "framework/tables.scss"; -@import "framework/notes.scss"; -@import "framework/timeline.scss"; -@import "framework/typography.scss"; -@import "framework/zen.scss"; +@import "framework/animations"; +@import "framework/avatar"; +@import "framework/asciidoctor"; +@import "framework/blocks"; +@import "framework/buttons"; +@import "framework/badges"; +@import "framework/calendar"; +@import "framework/callout"; +@import "framework/common"; +@import "framework/dropdowns"; +@import "framework/files"; +@import "framework/filters"; +@import "framework/flash"; +@import "framework/forms"; +@import "framework/gfm"; +@import "framework/header"; +@import "framework/highlight"; +@import "framework/issue_box"; +@import "framework/jquery"; +@import "framework/lists"; +@import "framework/logo"; +@import "framework/markdown_area"; +@import "framework/mobile"; +@import "framework/modal"; +@import "framework/nav"; +@import "framework/pagination"; +@import "framework/panels"; +@import "framework/selects"; +@import "framework/sidebar"; +@import "framework/tables"; +@import "framework/notes"; +@import "framework/timeline"; +@import "framework/typography"; +@import "framework/zen"; @import "framework/blank"; -@import "framework/wells.scss"; -@import "framework/page-header.scss"; -@import "framework/awards.scss"; -@import "framework/images.scss"; +@import "framework/wells"; +@import "framework/page-header"; +@import "framework/awards"; +@import "framework/images"; @import "framework/broadcast-messages"; -@import "framework/emojis.scss"; -@import "framework/emoji-sprites.scss"; -@import "framework/icons.scss"; -@import "framework/snippets.scss"; -@import "framework/memory_graph.scss"; -@import "framework/responsive-tables.scss"; +@import "framework/emojis"; +@import "framework/emoji-sprites"; +@import "framework/icons"; +@import "framework/snippets"; +@import "framework/memory_graph"; +@import "framework/responsive-tables"; diff --git a/app/assets/stylesheets/framework/awards.scss b/app/assets/stylesheets/framework/awards.scss index 19166757e64..e474839d95c 100644 --- a/app/assets/stylesheets/framework/awards.scss +++ b/app/assets/stylesheets/framework/awards.scss @@ -24,7 +24,7 @@ opacity: 0; transform: scale(.2); transform-origin: 0 -45px; - transition: .3s cubic-bezier(.67,.06,.19,1.44); + transition: .3s cubic-bezier(.67, .06, .19, 1.44); transition-property: transform, opacity; &.is-aligned-right { diff --git a/app/assets/stylesheets/framework/blank.scss b/app/assets/stylesheets/framework/blank.scss index c0224d3bfa9..6bb096fc5bd 100644 --- a/app/assets/stylesheets/framework/blank.scss +++ b/app/assets/stylesheets/framework/blank.scss @@ -1,9 +1,5 @@ .blank-state-parent-container { - display: flex; - .section-container { - display: flex; - flex: 1; padding: 10px; } @@ -13,91 +9,42 @@ padding-bottom: 25px; border: 1px solid $border-color; border-radius: $border-radius-default; - - &.section-ee-trial { - display: flex; - align-items: center; - justify-content: center; - } - } -} - -.blank-state-welcome { - text-align: center; - - .blank-state-text { - margin-bottom: 0; } } .blank-state { padding-top: 20px; padding-bottom: 20px; -} - -.blank-state.ee-trial { - padding: 20px; text-align: center; -} - -.blank-state-no-icon { - padding-top: 40px; - padding-bottom: 40px; -} - -.blank-state-icon { - padding-bottom: 20px; - font-size: 56px; - svg { - display: block; - margin: auto; - } -} - -@media (min-width: $screen-sm-max) { - .section-welcome .blank-state-icon svg { - width: 130%; - } -} - -.blank-state-title { - margin-top: 0; - margin-bottom: 10px; - font-size: 18px; -} - -.blank-state-text { - margin-top: 0; - margin-bottom: $gl-padding; - font-size: 14px; + &.blank-state-welcome { + .blank-state-welcome-title { + font-size: 24px; + } - > strong { - font-weight: 600; + .blank-state-text { + margin-bottom: 0; + } } -} -.blank-state-welcome-title { - font-size: 24px; -} + .blank-state-icon { + padding-bottom: 20px; -@media (max-width: $screen-md-min) { - .blank-state-parent-container { - &, - .section-container { + svg { display: block; + margin: auto; } } - .blank-state { - text-align: center; + .blank-state-title { + margin-top: 0; + margin-bottom: 10px; + font-size: 18px; } - .blank-state-icon { - padding-bottom: 0; - } - - .blank-state-body { - margin-top: 15px; + .blank-state-text { + max-width: $container-text-max-width; + margin: 0 auto $gl-padding; + font-size: 14px; } } diff --git a/app/assets/stylesheets/framework/common.scss b/app/assets/stylesheets/framework/common.scss index 00c981f64c5..5e374360359 100644 --- a/app/assets/stylesheets/framework/common.scss +++ b/app/assets/stylesheets/framework/common.scss @@ -336,11 +336,6 @@ table { text-align: center; } -#nprogress .spinner { - top: 15px !important; - right: 10px !important; -} - .header-with-avatar { h3 { margin: 0; @@ -450,4 +445,3 @@ table { pointer-events: none; opacity: .5; } - diff --git a/app/assets/stylesheets/framework/filters.scss b/app/assets/stylesheets/framework/filters.scss index f05348ee4e3..7e4e5fd7f1c 100644 --- a/app/assets/stylesheets/framework/filters.scss +++ b/app/assets/stylesheets/framework/filters.scss @@ -368,7 +368,7 @@ margin-right: 0.3em; } - & > .value { + > .value { font-weight: 600; } } @@ -467,7 +467,7 @@ -webkit-flex-direction: column; flex-direction: column; - &> span { + > span { white-space: normal; word-break: break-all; } diff --git a/app/assets/stylesheets/framework/highlight.scss b/app/assets/stylesheets/framework/highlight.scss index 6d27d7568cf..71d5949b023 100644 --- a/app/assets/stylesheets/framework/highlight.scss +++ b/app/assets/stylesheets/framework/highlight.scss @@ -61,7 +61,7 @@ &:focus { outline: none; - & i { + i { visibility: visible; } } diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss index 3f032776d82..3405f142428 100644 --- a/app/assets/stylesheets/framework/variables.scss +++ b/app/assets/stylesheets/framework/variables.scss @@ -176,6 +176,7 @@ $header-height: 50px; $fixed-layout-width: 1280px; $limited-layout-width: 990px; $limited-layout-width-sm: 790px; +$container-text-max-width: 540px; $gl-avatar-size: 40px; $error-exclamation-point: $red-500; $border-radius-default: 3px; @@ -316,7 +317,7 @@ $badge-color: $gl-text-color-secondary; /* * Award emoji */ -$award-emoji-menu-shadow: rgba(0,0,0,.175); +$award-emoji-menu-shadow: rgba(0, 0, 0, .175); $award-emoji-positive-add-bg: #fed159; $award-emoji-positive-add-lines: #bb9c13; @@ -567,7 +568,7 @@ $kdb-color: #555; $kdb-border: #ccc; $kdb-border-bottom: #bbb; $kdb-shadow: #bbb; -$body-text-shadow: rgba(255,255,255,0.01); +$body-text-shadow: rgba(255, 255, 255, 0.01); /* * UI Dev Kit diff --git a/app/assets/stylesheets/highlight/white.scss b/app/assets/stylesheets/highlight/white.scss index 1daa10aef24..578f1902cce 100644 --- a/app/assets/stylesheets/highlight/white.scss +++ b/app/assets/stylesheets/highlight/white.scss @@ -113,7 +113,7 @@ $white-gc-bg: #eaf2f5; border-color: $line-removed-dark; a { - color: scale-color($line-number-old,$red: -30%, $green: -30%, $blue: -30%); + color: scale-color($line-number-old, $red: -30%, $green: -30%, $blue: -30%); } } @@ -122,7 +122,7 @@ $white-gc-bg: #eaf2f5; border-color: $line-added-dark; a { - color: scale-color($line-number-new,$red: -30%, $green: -30%, $blue: -30%); + color: scale-color($line-number-new, $red: -30%, $green: -30%, $blue: -30%); } } @@ -163,7 +163,7 @@ $white-gc-bg: #eaf2f5; background-color: $line-removed; &::before { - color: scale-color($line-number-old,$red: -30%, $green: -30%, $blue: -30%); + color: scale-color($line-number-old, $red: -30%, $green: -30%, $blue: -30%); } span.idiff { @@ -175,7 +175,7 @@ $white-gc-bg: #eaf2f5; background-color: $line-added; &::before { - color: scale-color($line-number-new,$red: -30%, $green: -30%, $blue: -30%); + color: scale-color($line-number-new, $red: -30%, $green: -30%, $blue: -30%); } span.idiff { diff --git a/app/assets/stylesheets/new_sidebar.scss b/app/assets/stylesheets/new_sidebar.scss index 96459fe31cc..07b487cd090 100644 --- a/app/assets/stylesheets/new_sidebar.scss +++ b/app/assets/stylesheets/new_sidebar.scss @@ -2,12 +2,12 @@ @import 'framework/tw_bootstrap_variables'; @import "bootstrap/variables"; -$active-background: rgba(0,0,0,.04); +$active-background: rgba(0, 0, 0, .04); $active-border: $indigo-500; $active-color: $indigo-700; $active-hover-background: $active-background; $active-hover-color: $gl-text-color; -$inactive-badge-background: rgba(0,0,0,.08); +$inactive-badge-background: rgba(0, 0, 0, .08); $hover-background: $indigo-700; $hover-color: $white-light; $inactive-color: $gl-text-color-secondary; diff --git a/app/assets/stylesheets/pages/builds.scss b/app/assets/stylesheets/pages/builds.scss index 23c06eca3c3..0393820dee6 100644 --- a/app/assets/stylesheets/pages/builds.scss +++ b/app/assets/stylesheets/pages/builds.scss @@ -6,26 +6,26 @@ @keyframes blinking-dots { 0% { background-color: rgba($white-light, 1); - box-shadow: 12px 0 0 0 rgba($white-light,0.2), - 24px 0 0 0 rgba($white-light,0.2); + box-shadow: 12px 0 0 0 rgba($white-light, 0.2), + 24px 0 0 0 rgba($white-light, 0.2); } 25% { background-color: rgba($white-light, 0.4); - box-shadow: 12px 0 0 0 rgba($white-light,2), - 24px 0 0 0 rgba($white-light,0.2); + box-shadow: 12px 0 0 0 rgba($white-light, 2), + 24px 0 0 0 rgba($white-light, 0.2); } 75% { background-color: rgba($white-light, 0.4); - box-shadow: 12px 0 0 0 rgba($white-light,0.2), - 24px 0 0 0 rgba($white-light,1); + box-shadow: 12px 0 0 0 rgba($white-light, 0.2), + 24px 0 0 0 rgba($white-light, 1); } 100% { background-color: rgba($white-light, 1); - box-shadow: 12px 0 0 0 rgba($white-light,0.2), - 24px 0 0 0 rgba($white-light,0.2); + box-shadow: 12px 0 0 0 rgba($white-light, 0.2), + 24px 0 0 0 rgba($white-light, 0.2); } } diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss index 7adf17dddb8..2db967547dd 100644 --- a/app/assets/stylesheets/pages/merge_requests.scss +++ b/app/assets/stylesheets/pages/merge_requests.scss @@ -96,7 +96,7 @@ overflow: visible; } - & > span { + > span { padding-right: 4px; } @@ -125,7 +125,7 @@ .dropdown-menu { margin-top: 11px; - z-index: 200; + z-index: 300; } .ci-action-icon-wrapper { diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss index 303425041df..64a48e226bc 100644 --- a/app/assets/stylesheets/pages/notes.scss +++ b/app/assets/stylesheets/pages/notes.scss @@ -250,7 +250,7 @@ ul.notes { } .note-text { - & p:first-child { + p:first-child { display: none; } diff --git a/app/assets/stylesheets/pages/pipeline_schedules.scss b/app/assets/stylesheets/pages/pipeline_schedules.scss index dc719a6ba94..284b38ad370 100644 --- a/app/assets/stylesheets/pages/pipeline_schedules.scss +++ b/app/assets/stylesheets/pages/pipeline_schedules.scss @@ -96,12 +96,12 @@ } &:last-child { - & .pipeline-variable-row-remove-button { + .pipeline-variable-row-remove-button { display: none; } @media (max-width: $screen-sm-max) { - & .pipeline-variable-value-input { + .pipeline-variable-value-input { margin-right: $pipeline-variable-remove-button-width; } } diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss index 7d7c34115f9..46434eab8f3 100644 --- a/app/assets/stylesheets/pages/projects.scss +++ b/app/assets/stylesheets/pages/projects.scss @@ -26,7 +26,7 @@ margin-bottom: 5px; } - & > .form-group { + > .form-group { padding-left: 0; } @@ -83,7 +83,7 @@ border: 1px solid $border-color; } - & + .select2 a { + + .select2 a { border-top-left-radius: 0; border-bottom-left-radius: 0; } diff --git a/app/assets/stylesheets/pages/todos.scss b/app/assets/stylesheets/pages/todos.scss index de652a79369..d7a9dda3770 100644 --- a/app/assets/stylesheets/pages/todos.scss +++ b/app/assets/stylesheets/pages/todos.scss @@ -81,7 +81,7 @@ .todo-title { display: flex; - & > .title-item { + > .title-item { -webkit-flex: 0 0 auto; flex: 0 0 auto; margin: 0 2px; diff --git a/app/assets/stylesheets/pages/wiki.scss b/app/assets/stylesheets/pages/wiki.scss index 94d0a39f397..45c21c5d274 100644 --- a/app/assets/stylesheets/pages/wiki.scss +++ b/app/assets/stylesheets/pages/wiki.scss @@ -147,13 +147,13 @@ } ul.wiki-pages-list.content-list { - & ul { + ul { list-style: none; margin-left: 0; padding-left: 15px; } - & ul li { + ul li { padding: 5px 0; } } diff --git a/app/controllers/concerns/requires_health_token.rb b/app/controllers/concerns/requires_health_token.rb deleted file mode 100644 index 34ab1a97649..00000000000 --- a/app/controllers/concerns/requires_health_token.rb +++ /dev/null @@ -1,25 +0,0 @@ -module RequiresHealthToken - extend ActiveSupport::Concern - included do - before_action :validate_health_check_access! - end - - private - - def validate_health_check_access! - render_404 unless token_valid? - end - - def token_valid? - token = params[:token].presence || request.headers['TOKEN'] - token.present? && - ActiveSupport::SecurityUtils.variable_size_secure_compare( - token, - current_application_settings.health_check_access_token - ) - end - - def render_404 - render file: Rails.root.join('public', '404'), layout: false, status: '404' - end -end diff --git a/app/controllers/concerns/requires_whitelisted_monitoring_client.rb b/app/controllers/concerns/requires_whitelisted_monitoring_client.rb new file mode 100644 index 00000000000..ad2f4bbc486 --- /dev/null +++ b/app/controllers/concerns/requires_whitelisted_monitoring_client.rb @@ -0,0 +1,33 @@ +module RequiresWhitelistedMonitoringClient + extend ActiveSupport::Concern + included do + before_action :validate_ip_whitelisted_or_valid_token! + end + + private + + def validate_ip_whitelisted_or_valid_token! + render_404 unless client_ip_whitelisted? || valid_token? + end + + def client_ip_whitelisted? + ip_whitelist.any? { |e| e.include?(Gitlab::RequestContext.client_ip) } + end + + def ip_whitelist + @ip_whitelist ||= Settings.monitoring.ip_whitelist.map(&IPAddr.method(:new)) + end + + def valid_token? + token = params[:token].presence || request.headers['TOKEN'] + token.present? && + ActiveSupport::SecurityUtils.variable_size_secure_compare( + token, + current_application_settings.health_check_access_token + ) + end + + def render_404 + render file: Rails.root.join('public', '404'), layout: false, status: '404' + end +end diff --git a/app/controllers/health_check_controller.rb b/app/controllers/health_check_controller.rb index 5d3109b7187..c3d18991fd4 100644 --- a/app/controllers/health_check_controller.rb +++ b/app/controllers/health_check_controller.rb @@ -1,3 +1,3 @@ class HealthCheckController < HealthCheck::HealthCheckController - include RequiresHealthToken + include RequiresWhitelistedMonitoringClient end diff --git a/app/controllers/health_controller.rb b/app/controllers/health_controller.rb index abc832e6ddc..98c2aaa3526 100644 --- a/app/controllers/health_controller.rb +++ b/app/controllers/health_controller.rb @@ -1,10 +1,13 @@ class HealthController < ActionController::Base protect_from_forgery with: :exception - include RequiresHealthToken + include RequiresWhitelistedMonitoringClient CHECKS = [ Gitlab::HealthChecks::DbCheck, - Gitlab::HealthChecks::RedisCheck, + Gitlab::HealthChecks::Redis::RedisCheck, + Gitlab::HealthChecks::Redis::CacheCheck, + Gitlab::HealthChecks::Redis::QueuesCheck, + Gitlab::HealthChecks::Redis::SharedStateCheck, Gitlab::HealthChecks::FsShardsCheck ].freeze diff --git a/app/controllers/metrics_controller.rb b/app/controllers/metrics_controller.rb index 0e9a19c0b6f..37587a52eaf 100644 --- a/app/controllers/metrics_controller.rb +++ b/app/controllers/metrics_controller.rb @@ -1,12 +1,12 @@ class MetricsController < ActionController::Base - include RequiresHealthToken + include RequiresWhitelistedMonitoringClient protect_from_forgery with: :exception before_action :validate_prometheus_metrics def index - render text: metrics_service.metrics_text, content_type: 'text/plain; verssion=0.0.4' + render text: metrics_service.metrics_text, content_type: 'text/plain; version=0.0.4' end private diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb index fb0fbb43fb1..c6d23898560 100644 --- a/app/models/ci/runner.rb +++ b/app/models/ci/runner.rb @@ -149,7 +149,7 @@ module Ci private def cleanup_runner_queue - Gitlab::Redis.with do |redis| + Gitlab::Redis::Queues.with do |redis| redis.del(runner_queue_key) end end diff --git a/app/models/project.rb b/app/models/project.rb index d5760164663..e50818e3dff 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -1386,15 +1386,15 @@ class Project < ActiveRecord::Base end def pushes_since_gc - Gitlab::Redis.with { |redis| redis.get(pushes_since_gc_redis_key).to_i } + Gitlab::Redis::SharedState.with { |redis| redis.get(pushes_since_gc_redis_shared_state_key).to_i } end def increment_pushes_since_gc - Gitlab::Redis.with { |redis| redis.incr(pushes_since_gc_redis_key) } + Gitlab::Redis::SharedState.with { |redis| redis.incr(pushes_since_gc_redis_shared_state_key) } end def reset_pushes_since_gc - Gitlab::Redis.with { |redis| redis.del(pushes_since_gc_redis_key) } + Gitlab::Redis::SharedState.with { |redis| redis.del(pushes_since_gc_redis_shared_state_key) } end def route_map_for(commit_sha) @@ -1457,7 +1457,7 @@ class Project < ActiveRecord::Base from && self != from end - def pushes_since_gc_redis_key + def pushes_since_gc_redis_shared_state_key "projects/#{id}/pushes_since_gc" end diff --git a/app/models/user.rb b/app/models/user.rb index 4b01c2f19f0..2d39b1c1c34 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -699,7 +699,7 @@ class User < ActiveRecord::Base end def sanitize_attrs - %w[name username skype linkedin twitter].each do |attr| + %w[username skype linkedin twitter].each do |attr| value = public_send(attr) public_send("#{attr}=", Sanitize.clean(value)) if value.present? end diff --git a/app/services/metrics_service.rb b/app/services/metrics_service.rb index d726db4e99b..c92f070601c 100644 --- a/app/services/metrics_service.rb +++ b/app/services/metrics_service.rb @@ -3,7 +3,10 @@ require 'prometheus/client/formats/text' class MetricsService CHECKS = [ Gitlab::HealthChecks::DbCheck, - Gitlab::HealthChecks::RedisCheck, + Gitlab::HealthChecks::Redis::RedisCheck, + Gitlab::HealthChecks::Redis::CacheCheck, + Gitlab::HealthChecks::Redis::QueuesCheck, + Gitlab::HealthChecks::Redis::SharedStateCheck, Gitlab::HealthChecks::FsShardsCheck ].freeze diff --git a/app/services/milestones/destroy_service.rb b/app/services/milestones/destroy_service.rb index e457212508f..600ebcfbecb 100644 --- a/app/services/milestones/destroy_service.rb +++ b/app/services/milestones/destroy_service.rb @@ -1,15 +1,17 @@ module Milestones class DestroyService < Milestones::BaseService def execute(milestone) + return unless milestone.is_project_milestone? + Milestone.transaction do update_params = { milestone: nil } milestone.issues.each do |issue| - Issues::UpdateService.new(project, current_user, update_params).execute(issue) + Issues::UpdateService.new(parent, current_user, update_params).execute(issue) end milestone.merge_requests.each do |merge_request| - MergeRequests::UpdateService.new(project, current_user, update_params).execute(merge_request) + MergeRequests::UpdateService.new(parent, current_user, update_params).execute(merge_request) end event_service.destroy_milestone(milestone, current_user) diff --git a/app/views/dashboard/projects/_blank_state_admin_welcome.html.haml b/app/views/dashboard/projects/_blank_state_admin_welcome.html.haml index 0319838bdb4..209afd4aab4 100644 --- a/app/views/dashboard/projects/_blank_state_admin_welcome.html.haml +++ b/app/views/dashboard/projects/_blank_state_admin_welcome.html.haml @@ -1,7 +1,7 @@ -.row.blank-state.clearfix - .col-md-1.col-md-offset-3.blank-state-icon +.blank-state + .blank-state-icon = custom_icon("add_new_user", size: 50) - .col-md-5.blank-state-body + .blank-state-body %h3.blank-state-title Add user %p.blank-state-text @@ -9,10 +9,10 @@ = link_to new_admin_user_path, class: "btn btn-new" do New user -.row.blank-state.clearfix - .col-md-1.col-md-offset-3.blank-state-icon +.blank-state + .blank-state-icon = custom_icon("configure_server", size: 50) - .col-md-5.blank-state-body + .blank-state-body %h3.blank-state-title Configure GitLab %p.blank-state-text @@ -21,10 +21,10 @@ Configure - if current_user.can_create_group? - .row.blank-state.clearfix - .col-md-1.col-md-offset-3.blank-state-icon + .blank-state + .blank-state-icon = custom_icon("add_new_group", size: 50) - .col-md-5.blank-state-body + .blank-state-body %h3.blank-state-title Create a group %p.blank-state-text diff --git a/app/views/dashboard/projects/_blank_state_welcome.html.haml b/app/views/dashboard/projects/_blank_state_welcome.html.haml index a079f0ac1a4..a93a3415ee1 100644 --- a/app/views/dashboard/projects/_blank_state_welcome.html.haml +++ b/app/views/dashboard/projects/_blank_state_welcome.html.haml @@ -1,10 +1,10 @@ - public_project_count = ProjectsFinder.new(current_user: current_user).execute.count - if current_user.can_create_group? - .row.blank-state.clearfix - .col-md-1.col-md-offset-3.blank-state-icon + .blank-state + .blank-state-icon = custom_icon("add_new_group", size: 50) - .col-md-5.blank-state-body + .blank-state-body %h3.blank-state-title Create a group for several dependent projects. %p.blank-state-text @@ -12,10 +12,10 @@ = link_to new_group_path, class: "btn btn-new" do New group -.row.blank-state.clearfix - .col-md-1.col-md-offset-3.blank-state-icon +.blank-state + .blank-state-icon = custom_icon("add_new_project", size: 50) - .col-md-5.blank-state-body + .blank-state-body %h3.blank-state-title Create a project %p.blank-state-text @@ -32,10 +32,10 @@ New project - if public_project_count > 0 - .row.blank-state.clearfix - .col-md-1.col-md-offset-3.blank-state-icon + .blank-state + .blank-state-icon = custom_icon("globe", size: 50) - .col-md-5.blank-state-body + .blank-state-body %h3.blank-state-title Explore public projects %p.blank-state-text diff --git a/app/views/dashboard/projects/_zero_authorized_projects.html.haml b/app/views/dashboard/projects/_zero_authorized_projects.html.haml index 94af033c1e3..ad3fac6d164 100644 --- a/app/views/dashboard/projects/_zero_authorized_projects.html.haml +++ b/app/views/dashboard/projects/_zero_authorized_projects.html.haml @@ -1,6 +1,6 @@ .row.blank-state-parent-container - .section-container - .container.section-body.section-welcome{ class: "#{ 'section-admin-welcome' if current_user.admin? }" } + .section-container.section-welcome{ class: "#{ 'section-admin-welcome' if current_user.admin? }" } + .container.section-body .blank-state.blank-state-welcome %h2.blank-state-welcome-title Welcome to GitLab diff --git a/app/views/help/ui.html.haml b/app/views/help/ui.html.haml index 615dd56afbd..48edbb8c16f 100644 --- a/app/views/help/ui.html.haml +++ b/app/views/help/ui.html.haml @@ -525,7 +525,7 @@ %h4 %code .file-holder - - blob = Snippet.new(content: "Wow\nSuch\nFile") + - blob = Snippet.new(content: "Wow\nSuch\nFile").blob .example .file-holder .js-file-title.file-title diff --git a/app/views/layouts/nav/_breadcrumbs.html.haml b/app/views/layouts/nav/_breadcrumbs.html.haml index 5f1641f4300..b0c1ab7420f 100644 --- a/app/views/layouts/nav/_breadcrumbs.html.haml +++ b/app/views/layouts/nav/_breadcrumbs.html.haml @@ -2,7 +2,7 @@ - hide_top_links = @hide_top_links || false %nav.breadcrumbs{ role: "navigation" } - .breadcrumbs-container{ class: container_class } + .breadcrumbs-container{ class: [container_class, @content_class] } .breadcrumbs-links.js-title-container - unless hide_top_links .title diff --git a/app/views/layouts/nav/_new_project_sidebar.html.haml b/app/views/layouts/nav/_new_project_sidebar.html.haml index cc731db3cc1..8838852803b 100644 --- a/app/views/layouts/nav/_new_project_sidebar.html.haml +++ b/app/views/layouts/nav/_new_project_sidebar.html.haml @@ -74,9 +74,9 @@ = nav_link(controller: @project.default_issues_tracker? ? [:issues, :labels, :milestones, :boards] : :issues) do = link_to project_issues_path(@project), title: 'Issues', class: 'shortcuts-issues' do %span - Issues - if @project.default_issues_tracker? %span.badge.count.issue_counter= number_with_delimiter(IssuesFinder.new(current_user, project_id: @project.id).execute.opened.count) + Issues %ul.sidebar-sub-level-items - if project_nav_tab?(:issues) && !current_controller?(:merge_requests) @@ -112,8 +112,8 @@ = nav_link(controller: @project.default_issues_tracker? ? :merge_requests : [:merge_requests, :labels, :milestones]) do = link_to project_merge_requests_path(@project), title: 'Merge Requests', class: 'shortcuts-merge_requests' do %span - Merge Requests %span.badge.count.merge_counter.js-merge-counter= number_with_delimiter(MergeRequestsFinder.new(current_user, project_id: @project.id).execute.opened.count) + Merge Requests - if project_nav_tab? :pipelines = nav_link(controller: [:pipelines, :builds, :jobs, :pipeline_schedules, :environments, :artifacts]) do diff --git a/app/views/projects/commit/show.html.haml b/app/views/projects/commit/show.html.haml index b778e8af121..07c83c0a590 100644 --- a/app/views/projects/commit/show.html.haml +++ b/app/views/projects/commit/show.html.haml @@ -1,6 +1,7 @@ - @no_container = true - container_class = !fluid_layout && diff_view == :inline ? 'container-limited' : '' - limited_container_width = fluid_layout ? '' : 'limit-container-width' +- @content_class = limited_container_width - page_title "#{@commit.title} (#{@commit.short_id})", "Commits" - page_description @commit.description = render "projects/commits/head" diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml index 7b8be58554a..b0b7575f0d1 100644 --- a/app/views/projects/new.html.haml +++ b/app/views/projects/new.html.haml @@ -9,8 +9,9 @@ .col-lg-3.profile-settings-sidebar %h4.prepend-top-0 New project - %p - Create or Import your project from popular Git services + - if import_sources_enabled? + %p + Create or Import your project from popular Git services .col-lg-9 = form_for @project, html: { class: 'new_project' } do |f| .row diff --git a/app/views/projects/pipeline_schedules/index.html.haml b/app/views/projects/pipeline_schedules/index.html.haml index 05fe80e5fed..c4ee064ac43 100644 --- a/app/views/projects/pipeline_schedules/index.html.haml +++ b/app/views/projects/pipeline_schedules/index.html.haml @@ -12,9 +12,10 @@ - schedule_path_proc = ->(scope) { pipeline_schedules_path(@project, scope: scope) } = render "tabs", schedule_path_proc: schedule_path_proc, all_schedules: @all_schedules, scope: @scope - .nav-controls - = link_to new_project_pipeline_schedule_path(@project), class: 'btn btn-create' do - %span= _('New schedule') + - if can?(current_user, :create_pipeline_schedule, @project) + .nav-controls + = link_to new_project_pipeline_schedule_path(@project), class: 'btn btn-create' do + %span= _('New schedule') - if @schedules.present? %ul.content-list diff --git a/app/views/projects/show.html.haml b/app/views/projects/show.html.haml index d413c4619be..a73e111ad6d 100644 --- a/app/views/projects/show.html.haml +++ b/app/views/projects/show.html.haml @@ -1,4 +1,5 @@ - @no_container = true +- @content_class = "limit-container-width" unless fluid_layout - flash_message_container = show_new_nav? ? :new_global_flash : :flash_message = content_for :meta_tags do diff --git a/app/views/projects/tree/show.html.haml b/app/views/projects/tree/show.html.haml index 130980556c1..f727f340bb9 100644 --- a/app/views/projects/tree/show.html.haml +++ b/app/views/projects/tree/show.html.haml @@ -1,4 +1,5 @@ - @no_container = true +- @content_class = "limit-container-width" unless fluid_layout - page_title @path.presence || _("Files"), @ref = content_for :meta_tags do |