diff options
author | Filipa Lacerda <filipa@gitlab.com> | 2018-10-24 10:57:58 +0000 |
---|---|---|
committer | Filipa Lacerda <filipa@gitlab.com> | 2018-10-24 10:57:58 +0000 |
commit | cb47f40d8fdae43540c22f9373962ce8ec41fc6b (patch) | |
tree | b02fb3246185e93a0f63e42e3aa46e4b261f61d2 /app | |
parent | 379b4d8a96dbdb3f9f7d16002f76218800b17ae2 (diff) | |
parent | 3b3aa28c4cf73ec166d915117b589afb87cbd8ab (diff) | |
download | gitlab-ce-cb47f40d8fdae43540c22f9373962ce8ec41fc6b.tar.gz |
Merge branch 'mr-file-list' into 'master'
Add list mode to file browser in diffs
Closes #51859
See merge request gitlab-org/gitlab-ce!22191
Diffstat (limited to 'app')
-rw-r--r-- | app/assets/javascripts/diffs/components/tree_list.vue | 116 | ||||
-rw-r--r-- | app/assets/javascripts/vue_shared/components/file_row.vue | 34 | ||||
-rw-r--r-- | app/assets/stylesheets/pages/diff.scss | 14 |
3 files changed, 140 insertions, 24 deletions
diff --git a/app/assets/javascripts/diffs/components/tree_list.vue b/app/assets/javascripts/diffs/components/tree_list.vue index cfe4273742f..34e836a570a 100644 --- a/app/assets/javascripts/diffs/components/tree_list.vue +++ b/app/assets/javascripts/diffs/components/tree_list.vue @@ -1,17 +1,30 @@ <script> import { mapActions, mapGetters, mapState } from 'vuex'; +import { TooltipDirective as Tooltip } from '@gitlab-org/gitlab-ui'; +import { convertPermissionToBoolean } from '~/lib/utils/common_utils'; import Icon from '~/vue_shared/components/icon.vue'; import FileRow from '~/vue_shared/components/file_row.vue'; import FileRowStats from './file_row_stats.vue'; +const treeListStorageKey = 'mr_diff_tree_list'; + export default { + directives: { + Tooltip, + }, components: { Icon, FileRow, }, data() { + const treeListStored = localStorage.getItem(treeListStorageKey); + const renderTreeList = treeListStored !== null ? + convertPermissionToBoolean(treeListStored) : true; + return { search: '', + renderTreeList, + focusSearch: false, }; }, computed: { @@ -20,15 +33,35 @@ export default { filteredTreeList() { const search = this.search.toLowerCase().trim(); - if (search === '') return this.tree; + if (search === '') return this.renderTreeList ? this.tree : this.allBlobs; return this.allBlobs.filter(f => f.name.toLowerCase().indexOf(search) >= 0); }, + rowDisplayTextKey() { + if (this.renderTreeList && this.search.trim() === '') { + return 'name'; + } + + return 'path'; + }, }, methods: { ...mapActions('diffs', ['toggleTreeOpen', 'scrollToFile']), clearSearch() { this.search = ''; + this.toggleFocusSearch(false); + }, + toggleRenderTreeList(toggle) { + this.renderTreeList = toggle; + localStorage.setItem(treeListStorageKey, this.renderTreeList); + }, + toggleFocusSearch(toggle) { + this.focusSearch = toggle; + }, + blurSearch() { + if (this.search.trim() === '') { + this.toggleFocusSearch(false); + } }, }, FileRowStats, @@ -37,28 +70,67 @@ export default { <template> <div class="tree-list-holder d-flex flex-column"> - <div class="append-bottom-8 position-relative tree-list-search"> - <icon - name="search" - class="position-absolute tree-list-icon" - /> - <input - v-model="search" - :placeholder="s__('MergeRequest|Filter files')" - type="search" - class="form-control" - /> - <button - v-show="search" - :aria-label="__('Clear search')" - type="button" - class="position-absolute tree-list-icon tree-list-clear-icon border-0 p-0" - @click="clearSearch" - > + <div class="append-bottom-8 position-relative tree-list-search d-flex"> + <div class="flex-fill d-flex"> <icon - name="close" + name="search" + class="position-absolute tree-list-icon" + /> + <input + v-model="search" + :placeholder="s__('MergeRequest|Filter files')" + type="search" + class="form-control" + @focus="toggleFocusSearch(true)" + @blur="blurSearch" /> - </button> + <button + v-show="search" + :aria-label="__('Clear search')" + type="button" + class="position-absolute bg-transparent tree-list-icon tree-list-clear-icon border-0 p-0" + @click="clearSearch" + > + <icon + name="close" + /> + </button> + </div> + <div + v-show="!focusSearch" + class="btn-group prepend-left-8 tree-list-view-toggle" + > + <button + v-tooltip.hover + :aria-label="__('List view')" + :title="__('List view')" + :class="{ + active: !renderTreeList + }" + class="btn btn-default pt-0 pb-0 d-flex align-items-center" + type="button" + @click="toggleRenderTreeList(false)" + > + <icon + name="hamburger" + /> + </button> + <button + v-tooltip.hover + :aria-label="__('Tree view')" + :title="__('Tree view')" + :class="{ + active: renderTreeList + }" + class="btn btn-default pt-0 pb-0 d-flex align-items-center" + type="button" + @click="toggleRenderTreeList(true)" + > + <icon + name="file-tree" + /> + </button> + </div> </div> <div class="tree-list-scroll" @@ -72,6 +144,8 @@ export default { :hide-extra-on-tree="true" :extra-component="$options.FileRowStats" :show-changed-icon="true" + :display-text-key="rowDisplayTextKey" + :should-truncate-start="true" @toggleTreeOpen="toggleTreeOpen" @clickFile="scrollToFile" /> diff --git a/app/assets/javascripts/vue_shared/components/file_row.vue b/app/assets/javascripts/vue_shared/components/file_row.vue index 36a345130c0..2d89a156117 100644 --- a/app/assets/javascripts/vue_shared/components/file_row.vue +++ b/app/assets/javascripts/vue_shared/components/file_row.vue @@ -34,10 +34,21 @@ export default { required: false, default: false, }, + displayTextKey: { + type: String, + required: false, + default: 'name', + }, + shouldTruncateStart: { + type: Boolean, + required: false, + default: false, + }, }, data() { return { mouseOver: false, + truncateStart: 0, }; }, computed: { @@ -60,6 +71,15 @@ export default { 'is-open': this.file.opened, }; }, + outputText() { + const text = this.file[this.displayTextKey]; + + if (this.truncateStart === 0) { + return text; + } + + return `...${text.substring(this.truncateStart, text.length)}`; + }, }, watch: { 'file.active': function fileActiveWatch(active) { @@ -72,6 +92,15 @@ export default { if (this.hasPathAtCurrentRoute()) { this.scrollIntoView(true); } + + if (this.shouldTruncateStart) { + const { scrollWidth, offsetWidth } = this.$refs.textOutput; + const textOverflow = scrollWidth - offsetWidth; + + if (textOverflow > 0) { + this.truncateStart = Math.ceil(textOverflow / 5) + 3; + } + } }, methods: { toggleTreeOpen(path) { @@ -139,6 +168,7 @@ export default { class="file-row-name-container" > <span + ref="textOutput" :style="levelIndentation" class="file-row-name str-truncated" > @@ -156,7 +186,7 @@ export default { :size="16" class="append-right-5" /> - {{ file.name }} + {{ outputText }} </span> <component :is="extraComponent" @@ -175,6 +205,8 @@ export default { :hide-extra-on-tree="hideExtraOnTree" :extra-component="extraComponent" :show-changed-icon="showChangedIcon" + :display-text-key="displayTextKey" + :should-truncate-start="shouldTruncateStart" @toggleTreeOpen="toggleTreeOpen" @clickFile="clickedFile" /> diff --git a/app/assets/stylesheets/pages/diff.scss b/app/assets/stylesheets/pages/diff.scss index 8d884ad6891..52c91266ff4 100644 --- a/app/assets/stylesheets/pages/diff.scss +++ b/app/assets/stylesheets/pages/diff.scss @@ -1027,8 +1027,12 @@ overflow-x: auto; } -.tree-list-search .form-control { - padding-left: 30px; +.tree-list-search { + flex: 0 0 34px; + + .form-control { + padding-left: 30px; + } } .tree-list-icon { @@ -1063,3 +1067,9 @@ } } } + +.tree-list-view-toggle { + svg { + top: 0; + } +} |