diff options
25 files changed, 168 insertions, 164 deletions
diff --git a/app/assets/javascripts/ide/components/commit_sidebar/list.vue b/app/assets/javascripts/ide/components/commit_sidebar/list.vue index 3d59410cbc2..d0fb0e3d99e 100644 --- a/app/assets/javascripts/ide/components/commit_sidebar/list.vue +++ b/app/assets/javascripts/ide/components/commit_sidebar/list.vue @@ -34,6 +34,10 @@ export default { type: String, required: true, }, + actionBtnIcon: { + type: String, + required: true, + }, itemActionComponent: { type: String, required: true, @@ -53,26 +57,21 @@ export default { required: true, }, }, - data() { - return { - showActionButton: false, - }; - }, computed: { titleText() { return sprintf(__('%{title} changes'), { title: this.title, }); }, + filesLength() { + return this.fileList.length; + }, }, methods: { ...mapActions(['stageAllChanges', 'unstageAllChanges']), actionBtnClicked() { this[this.action](); }, - setShowActionButton(show) { - this.showActionButton = show; - }, }, }; </script> @@ -83,8 +82,6 @@ export default { > <header class="multi-file-commit-panel-header" - @mouseenter="setShowActionButton(true)" - @mouseleave="setShowActionButton(false)" > <div class="multi-file-commit-panel-header-title" @@ -95,24 +92,40 @@ export default { :size="18" /> {{ titleText }} - <span - v-show="!showActionButton" - class="ide-commit-file-count" - > - {{ fileList.length }} - </span> - <button - v-show="showActionButton" - type="button" - class="btn btn-blank btn-link ide-staged-action-btn" - @click="actionBtnClicked" - > - {{ actionBtnText }} - </button> + <div class="d-flex ml-auto"> + <button + v-tooltip + v-show="filesLength" + :class="{ + 'd-flex': filesLength + }" + :title="actionBtnText" + type="button" + class="btn btn-default ide-staged-action-btn p-0 order-1 align-items-center" + data-placement="bottom" + data-container="body" + data-boundary="viewport" + @click="actionBtnClicked" + > + <icon + :name="actionBtnIcon" + :size="12" + class="ml-auto mr-auto" + /> + </button> + <span + :class="{ + 'rounded-right': !filesLength + }" + class="ide-commit-file-count order-0 rounded-left text-center" + > + {{ filesLength }} + </span> + </div> </div> </header> <ul - v-if="fileList.length" + v-if="filesLength" class="multi-file-commit-list list-unstyled append-bottom-0" > <li diff --git a/app/assets/javascripts/ide/components/commit_sidebar/list_item.vue b/app/assets/javascripts/ide/components/commit_sidebar/list_item.vue index 2ecf9af4bf0..5cda7967130 100644 --- a/app/assets/javascripts/ide/components/commit_sidebar/list_item.vue +++ b/app/assets/javascripts/ide/components/commit_sidebar/list_item.vue @@ -1,5 +1,6 @@ <script> import { mapActions } from 'vuex'; +import tooltip from '~/vue_shared/directives/tooltip'; import Icon from '~/vue_shared/components/icon.vue'; import StageButton from './stage_button.vue'; import UnstageButton from './unstage_button.vue'; @@ -11,6 +12,9 @@ export default { StageButton, UnstageButton, }, + directives: { + tooltip, + }, props: { file: { type: Object, @@ -50,6 +54,9 @@ export default { isActive() { return this.activeFileKey === this.fullKey; }, + tooltipTitle() { + return this.file.path === this.file.name ? '' : this.file.path; + }, }, methods: { ...mapActions([ @@ -81,29 +88,30 @@ export default { </script> <template> - <div - :class="{ - 'is-active': isActive - }" - class="multi-file-commit-list-item" - > + <div class="multi-file-commit-list-item position-relative"> <button + v-tooltip + :title="tooltipTitle" + :class="{ + 'is-active': isActive + }" type="button" - class="multi-file-commit-list-path" + class="multi-file-commit-list-path w-100 border-0 ml-0 mr-0" @dblclick="fileAction" @click="openFileInEditor" > - <span class="multi-file-commit-list-file-path"> + <span class="multi-file-commit-list-file-path d-flex align-items-center"> <icon :name="iconName" :size="16" :css-classes="iconClass" - />{{ file.path }} + />{{ file.name }} </span> </button> <component :is="actionComponent" :path="file.path" + class="d-flex position-absolute" /> </div> </template> diff --git a/app/assets/javascripts/ide/components/commit_sidebar/stage_button.vue b/app/assets/javascripts/ide/components/commit_sidebar/stage_button.vue index a786ec80ac2..7014b9f605e 100644 --- a/app/assets/javascripts/ide/components/commit_sidebar/stage_button.vue +++ b/app/assets/javascripts/ide/components/commit_sidebar/stage_button.vue @@ -25,15 +25,17 @@ export default { <template> <div v-once - class="multi-file-discard-btn" + class="multi-file-discard-btn dropdown" > <button v-tooltip :aria-label="__('Stage changes')" :title="__('Stage changes')" type="button" - class="btn btn-blank append-right-5" + class="btn btn-blank append-right-5 d-flex align-items-center" data-container="body" + data-boundary="viewport" + data-placement="bottom" @click.stop="stageChange(path)" > <icon @@ -43,17 +45,31 @@ export default { </button> <button v-tooltip - :aria-label="__('Discard changes')" - :title="__('Discard changes')" + :title="__('More actions')" type="button" - class="btn btn-blank" + class="btn btn-blank d-flex align-items-center" data-container="body" - @click.stop="discardFileChanges(path)" + data-boundary="viewport" + data-placement="bottom" + data-toggle="dropdown" + data-display="static" > <icon :size="12" - name="remove" + name="more" /> </button> + <div class="dropdown-menu dropdown-menu-right"> + <ul> + <li> + <button + type="button" + @click.stop="discardFileChanges(path)" + > + {{ __('Discard changes') }} + </button> + </li> + </ul> + </div> </div> </template> diff --git a/app/assets/javascripts/ide/components/commit_sidebar/unstage_button.vue b/app/assets/javascripts/ide/components/commit_sidebar/unstage_button.vue index 34b366f63ac..9cec73ec00e 100644 --- a/app/assets/javascripts/ide/components/commit_sidebar/unstage_button.vue +++ b/app/assets/javascripts/ide/components/commit_sidebar/unstage_button.vue @@ -32,8 +32,10 @@ export default { :aria-label="__('Unstage changes')" :title="__('Unstage changes')" type="button" - class="btn btn-blank" + class="btn btn-blank d-flex align-items-center" data-container="body" + data-boundary="viewport" + data-placement="bottom" @click="unstageChange(path)" > <icon diff --git a/app/assets/javascripts/ide/components/repo_commit_section.vue b/app/assets/javascripts/ide/components/repo_commit_section.vue index 01df0019fd4..c2c678ff0be 100644 --- a/app/assets/javascripts/ide/components/repo_commit_section.vue +++ b/app/assets/javascripts/ide/components/repo_commit_section.vue @@ -93,23 +93,25 @@ export default { :title="__('Unstaged')" :key-prefix="$options.stageKeys.unstaged" :file-list="changedFiles" - :action-btn-text="__('Stage all')" + :action-btn-text="__('Stage all changes')" :active-file-key="activeFileKey" - class="is-first" - icon-name="unstaged" action="stageAllChanges" + action-btn-icon="mobile-issue-close" item-action-component="stage-button" + class="is-first" + icon-name="unstaged" /> <commit-files-list :title="__('Staged')" :key-prefix="$options.stageKeys.staged" :file-list="stagedFiles" - :action-btn-text="__('Unstage all')" + :action-btn-text="__('Unstage all changes')" :staged-list="true" :active-file-key="activeFileKey" - icon-name="staged" action="unstageAllChanges" + action-btn-icon="history" item-action-component="unstage-button" + icon-name="staged" /> </template> <empty-state diff --git a/app/assets/javascripts/ide/lib/editor_options.js b/app/assets/javascripts/ide/lib/editor_options.js index 9f895d49f2e..e35595ab1fd 100644 --- a/app/assets/javascripts/ide/lib/editor_options.js +++ b/app/assets/javascripts/ide/lib/editor_options.js @@ -12,5 +12,6 @@ export const defaultEditorOptions = { export default [ { readOnly: model => !!model.file.file_lock, + quickSuggestions: model => !(model.language === 'markdown'), }, ]; diff --git a/app/assets/javascripts/pipelines/components/graph/action_component.vue b/app/assets/javascripts/pipelines/components/graph/action_component.vue index db0505a55fe..1f152ed438d 100644 --- a/app/assets/javascripts/pipelines/components/graph/action_component.vue +++ b/app/assets/javascripts/pipelines/components/graph/action_component.vue @@ -91,6 +91,7 @@ export default { class="js-ci-action btn btn-blank btn-transparent ci-action-icon-container ci-action-icon-wrapper" data-container="body" + data-boundary="viewport" @click="onClickAction" > <icon :name="actionIcon"/> diff --git a/app/assets/stylesheets/bootstrap_migration.scss b/app/assets/stylesheets/bootstrap_migration.scss index 5da0e672288..c3ba62805dc 100644 --- a/app/assets/stylesheets/bootstrap_migration.scss +++ b/app/assets/stylesheets/bootstrap_migration.scss @@ -128,11 +128,6 @@ table { border-spacing: 0; } -.tooltip { - // Fix bootstrap4 bug whereby tooltips flicker when they are hovered over their borders - pointer-events: none; -} - .popover { font-size: 14px; } diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss index 04d2a049f7d..3ee992879d1 100644 --- a/app/assets/stylesheets/framework/variables.scss +++ b/app/assets/stylesheets/framework/variables.scss @@ -834,3 +834,4 @@ $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/pages/repo.scss b/app/assets/stylesheets/pages/repo.scss index 4b8a3db1d06..0a56153203c 100644 --- a/app/assets/stylesheets/pages/repo.scss +++ b/app/assets/stylesheets/pages/repo.scss @@ -540,36 +540,12 @@ margin-right: -$grid-size; min-height: 60px; - .multi-file-commit-list-item { - margin-left: 0; - margin-right: 0; - } - &.form-text.text-muted { margin-left: 0; right: 0; } } -.multi-file-commit-list-item { - &.is-active { - background-color: $white-normal; - } - - .multi-file-discard-btn { - display: none; - margin-top: -2px; - margin-left: auto; - color: $gl-link-color; - } - - &:hover { - .multi-file-discard-btn { - display: flex; - } - } -} - .multi-file-addition, .multi-file-addition-solid { color: $green-500; @@ -599,7 +575,7 @@ } } -.multi-file-commit-list-item, +.multi-file-commit-list-path, .ide-file-list .file { display: flex; align-items: center; @@ -616,11 +592,9 @@ } .multi-file-commit-list-path { - padding: 0; - background: none; - border: 0; - text-align: left; - width: 100%; + &.is-active { + background-color: $white-normal; + } &:hover, &:focus { @@ -635,7 +609,7 @@ } .multi-file-commit-list-file-path { - @include str-truncated(100%); + @include str-truncated(calc(100% - 30px)); &:hover { text-decoration: underline; @@ -646,6 +620,16 @@ } } +.multi-file-discard-btn { + top: 4px; + right: 8px; + bottom: 4px; + + svg { + top: 0; + } +} + .multi-file-commit-form { position: relative; background-color: $white-light; @@ -840,18 +824,20 @@ } .ide-staged-action-btn { - margin-left: auto; - line-height: 22px; + width: 22px; + margin-left: -1px; + border-top-left-radius: 0; + border-bottom-left-radius: 0; + + > svg { + top: 0; + } } .ide-commit-file-count { min-width: 22px; - margin-left: auto; background-color: $gray-light; - border-radius: $border-radius-default; border: 1px solid $white-dark; - line-height: 20px; - text-align: center; } .ide-commit-radios { diff --git a/app/uploaders/favicon_uploader.rb b/app/uploaders/favicon_uploader.rb index 09afc63a5aa..3639375d474 100644 --- a/app/uploaders/favicon_uploader.rb +++ b/app/uploaders/favicon_uploader.rb @@ -1,17 +1,6 @@ class FaviconUploader < AttachmentUploader EXTENSION_WHITELIST = %w[png ico].freeze - include CarrierWave::MiniMagick - - version :favicon_main do - process resize_to_fill: [32, 32] - process convert: 'png' - - def full_filename(filename) - filename_for_different_format(super(filename), 'png') - end - end - def extension_whitelist EXTENSION_WHITELIST end diff --git a/app/views/admin/appearances/_form.html.haml b/app/views/admin/appearances/_form.html.haml index 94db374040c..a0861870ba4 100644 --- a/app/views/admin/appearances/_form.html.haml +++ b/app/views/admin/appearances/_form.html.haml @@ -25,7 +25,7 @@ = f.label :favicon, 'Favicon', class: 'col-sm-2 col-form-label' .col-sm-10 - if @appearance.favicon? - = image_tag @appearance.favicon.favicon_main.url, class: 'appearance-light-logo-preview' + = image_tag @appearance.favicon_url, class: 'appearance-light-logo-preview' - if @appearance.persisted? %br = link_to 'Remove favicon', favicon_admin_appearances_path, data: { confirm: "Favicon will be removed. Are you sure?"}, method: :delete, class: "btn btn-inverted btn-remove btn-sm remove-logo" @@ -33,9 +33,9 @@ = f.hidden_field :favicon_cache = f.file_field :favicon, class: '' .hint - Maximum file size is 1MB. Allowed image formats are #{favicon_extension_whitelist}. + Maximum file size is 1MB. Image size must be 32x32px. Allowed image formats are #{favicon_extension_whitelist}. %br - The resulting favicons will be cropped to be square and scaled down to a size of 32x32 px. + Images with incorrect dimensions are not resized automatically, and may result in unexpected behavior. %fieldset.sign-in %legend diff --git a/app/views/shared/issuable/_milestone_dropdown.html.haml b/app/views/shared/issuable/_milestone_dropdown.html.haml index 955b8866c2c..37625a4a163 100644 --- a/app/views/shared/issuable/_milestone_dropdown.html.haml +++ b/app/views/shared/issuable/_milestone_dropdown.html.haml @@ -1,6 +1,8 @@ - project = @target_project || @project - extra_class = extra_class || '' - show_menu_above = show_menu_above || false +- selected = local_assigns.fetch(:selected, nil) + - selected_text = selected.try(:title) || params[:milestone_title] - dropdown_title = local_assigns.fetch(:dropdown_title, "Filter by milestone") - if selected.present? || params[:milestone_title].present? diff --git a/changelogs/unreleased/fix-web-ide-disable-markdown-autocomplete.yml b/changelogs/unreleased/fix-web-ide-disable-markdown-autocomplete.yml new file mode 100644 index 00000000000..6a4d9b6c8c4 --- /dev/null +++ b/changelogs/unreleased/fix-web-ide-disable-markdown-autocomplete.yml @@ -0,0 +1,5 @@ +--- +title: Disabled Web IDE autocomplete suggestions for Markdown files. +merge_request: +author: Isaac Smith +type: fixed diff --git a/changelogs/unreleased/ide-commit-actions-update.yml b/changelogs/unreleased/ide-commit-actions-update.yml new file mode 100644 index 00000000000..35bee94e156 --- /dev/null +++ b/changelogs/unreleased/ide-commit-actions-update.yml @@ -0,0 +1,5 @@ +--- +title: Improve Web IDE commit flow +merge_request: +author: +type: changed diff --git a/lib/gitlab/favicon.rb b/lib/gitlab/favicon.rb index 451c9daf761..faf7016d73a 100644 --- a/lib/gitlab/favicon.rb +++ b/lib/gitlab/favicon.rb @@ -2,7 +2,7 @@ module Gitlab class Favicon class << self def main - return appearance_favicon.favicon_main.url if appearance_favicon.exists? + return appearance_favicon.url if appearance_favicon.exists? image_name = if Gitlab::Utils.to_boolean(ENV['CANARY']) diff --git a/spec/controllers/uploads_controller_spec.rb b/spec/controllers/uploads_controller_spec.rb index 1df2c954893..eb94d395a9e 100644 --- a/spec/controllers/uploads_controller_spec.rb +++ b/spec/controllers/uploads_controller_spec.rb @@ -580,23 +580,6 @@ describe UploadsController do expect(response).to have_gitlab_http_status(404) end end - - context 'has a valid filename on the version file' do - it 'successfully returns the file' do - get :show, model: 'appearance', mounted_as: 'favicon', id: appearance.id, filename: 'favicon_main_dk.png' - - expect(response).to have_gitlab_http_status(200) - expect(response.header['Content-Disposition']).to end_with 'filename="favicon_main_dk.png"' - end - end - - context 'has an invalid filename on the version file' do - it 'returns a 404' do - get :show, model: 'appearance', mounted_as: 'favicon', id: appearance.id, filename: 'favicon_bogusversion_dk.png' - - expect(response).to have_gitlab_http_status(404) - end - end end end end diff --git a/spec/javascripts/ide/components/commit_sidebar/list_item_spec.js b/spec/javascripts/ide/components/commit_sidebar/list_item_spec.js index 8f7cf24c22f..bf96170f703 100644 --- a/spec/javascripts/ide/components/commit_sidebar/list_item_spec.js +++ b/spec/javascripts/ide/components/commit_sidebar/list_item_spec.js @@ -93,14 +93,14 @@ describe('Multi-file editor commit sidebar list item', () => { describe('is active', () => { it('does not add active class when dont keys match', () => { - expect(vm.$el.classList).not.toContain('is-active'); + expect(vm.$el.querySelector('.is-active')).toBe(null); }); it('adds active class when keys match', done => { vm.keyPrefix = 'staged'; vm.$nextTick(() => { - expect(vm.$el.classList).toContain('is-active'); + expect(vm.$el.querySelector('.is-active')).not.toBe(null); done(); }); diff --git a/spec/javascripts/ide/components/commit_sidebar/list_spec.js b/spec/javascripts/ide/components/commit_sidebar/list_spec.js index 6fb52378386..b786be55019 100644 --- a/spec/javascripts/ide/components/commit_sidebar/list_spec.js +++ b/spec/javascripts/ide/components/commit_sidebar/list_spec.js @@ -16,6 +16,7 @@ describe('Multi-file editor commit sidebar list', () => { iconName: 'staged', action: 'stageAllChanges', actionBtnText: 'stage all', + actionBtnIcon: 'history', itemActionComponent: 'stage-button', activeFileKey: 'staged-testing', keyPrefix: 'staged', @@ -42,7 +43,7 @@ describe('Multi-file editor commit sidebar list', () => { }); it('renders list', () => { - expect(vm.$el.querySelectorAll('li').length).toBe(1); + expect(vm.$el.querySelectorAll('.multi-file-commit-list > li').length).toBe(1); }); }); diff --git a/spec/javascripts/ide/components/commit_sidebar/stage_button_spec.js b/spec/javascripts/ide/components/commit_sidebar/stage_button_spec.js index 6bf8710bda7..a5b906da8a1 100644 --- a/spec/javascripts/ide/components/commit_sidebar/stage_button_spec.js +++ b/spec/javascripts/ide/components/commit_sidebar/stage_button_spec.js @@ -39,7 +39,7 @@ describe('IDE stage file button', () => { }); it('calls store with discard button', () => { - vm.$el.querySelectorAll('.btn')[1].click(); + vm.$el.querySelector('.dropdown-menu button').click(); expect(vm.discardFileChanges).toHaveBeenCalledWith(f.path); }); diff --git a/spec/javascripts/ide/components/repo_commit_section_spec.js b/spec/javascripts/ide/components/repo_commit_section_spec.js index 531bcd6e540..6bf309fb4bf 100644 --- a/spec/javascripts/ide/components/repo_commit_section_spec.js +++ b/spec/javascripts/ide/components/repo_commit_section_spec.js @@ -111,7 +111,7 @@ describe('RepoCommitSection', () => { }); it('renders a commit section', () => { - const changedFileElements = [...vm.$el.querySelectorAll('.multi-file-commit-list li')]; + const changedFileElements = [...vm.$el.querySelectorAll('.multi-file-commit-list > li')]; const allFiles = vm.$store.state.changedFiles.concat(vm.$store.state.stagedFiles); expect(changedFileElements.length).toEqual(4); @@ -140,22 +140,26 @@ describe('RepoCommitSection', () => { vm.$el.querySelector('.multi-file-discard-btn .btn').click(); Vue.nextTick(() => { - expect(vm.$el.querySelector('.ide-commit-list-container').querySelectorAll('li').length).toBe( - 1, - ); + expect( + vm.$el + .querySelector('.ide-commit-list-container') + .querySelectorAll('.multi-file-commit-list > li').length, + ).toBe(1); done(); }); }); it('discards a single file', done => { - vm.$el.querySelectorAll('.multi-file-discard-btn .btn')[1].click(); + vm.$el.querySelector('.multi-file-discard-btn .dropdown-menu button').click(); Vue.nextTick(() => { expect(vm.$el.querySelector('.ide-commit-list-container').textContent).not.toContain('file1'); - expect(vm.$el.querySelector('.ide-commit-list-container').querySelectorAll('li').length).toBe( - 1, - ); + expect( + vm.$el + .querySelector('.ide-commit-list-container') + .querySelectorAll('.multi-file-commit-list > li').length, + ).toBe(1); done(); }); diff --git a/spec/javascripts/ide/lib/editor_spec.js b/spec/javascripts/ide/lib/editor_spec.js index c1932284d53..c2cb964ea87 100644 --- a/spec/javascripts/ide/lib/editor_spec.js +++ b/spec/javascripts/ide/lib/editor_spec.js @@ -263,4 +263,23 @@ describe('Multi-file editor library', () => { expect(instance.isDiffEditorType).toBe(false); }); }); + + it('sets quickSuggestions to false when language is markdown', () => { + instance.createInstance(holder); + + spyOn(instance.instance, 'updateOptions').and.callThrough(); + + const model = instance.createModel({ + ...file(), + key: 'index.md', + path: 'index.md', + }); + + instance.attachModel(model); + + expect(instance.instance.updateOptions).toHaveBeenCalledWith({ + readOnly: false, + quickSuggestions: false, + }); + }); }); diff --git a/spec/lib/gitlab/favicon_spec.rb b/spec/lib/gitlab/favicon_spec.rb index 08c4a474217..f36111a4946 100644 --- a/spec/lib/gitlab/favicon_spec.rb +++ b/spec/lib/gitlab/favicon_spec.rb @@ -19,7 +19,7 @@ RSpec.describe Gitlab::Favicon, :request_store do it 'uses the custom favicon if a favicon appearance is present' do create :appearance, favicon: fixture_file_upload('spec/fixtures/dk.png') - expect(described_class.main).to match %r{/uploads/-/system/appearance/favicon/\d+/favicon_main_dk.png} + expect(described_class.main).to match %r{/uploads/-/system/appearance/favicon/\d+/dk.png} end end diff --git a/spec/models/project_services/jira_service_spec.rb b/spec/models/project_services/jira_service_spec.rb index b9f1c7dd5df..6c637533c6b 100644 --- a/spec/models/project_services/jira_service_spec.rb +++ b/spec/models/project_services/jira_service_spec.rb @@ -478,7 +478,7 @@ describe JiraService do create :appearance, favicon: fixture_file_upload('spec/fixtures/dk.png') props = described_class.new.send(:build_remote_link_props, url: 'http://example.com', title: 'title') - expect(props[:object][:icon][:url16x16]).to match %r{^http://localhost/uploads/-/system/appearance/favicon/\d+/favicon_main_dk.png$} + expect(props[:object][:icon][:url16x16]).to match %r{^http://localhost/uploads/-/system/appearance/favicon/\d+/dk.png$} end end end diff --git a/spec/uploaders/favicon_uploader_spec.rb b/spec/uploaders/favicon_uploader_spec.rb deleted file mode 100644 index 37deea8ab90..00000000000 --- a/spec/uploaders/favicon_uploader_spec.rb +++ /dev/null @@ -1,29 +0,0 @@ -require 'spec_helper' - -RSpec.describe FaviconUploader do - include CarrierWave::Test::Matchers - - let(:uploader) { described_class.new(build_stubbed(:user)) } - - after do - uploader.remove! - end - - def upload_fixture(filename) - fixture_file_upload("spec/fixtures/#{filename}") - end - - context 'versions' do - before do - uploader.store!(upload_fixture('dk.png')) - end - - it 'has the correct format' do - expect(uploader.favicon_main).to be_format('png') - end - - it 'has the correct dimensions' do - expect(uploader.favicon_main).to have_dimensions(32, 32) - end - end -end |