diff options
author | Phil Hughes <me@iamphill.com> | 2018-04-11 17:12:01 +0100 |
---|---|---|
committer | Phil Hughes <me@iamphill.com> | 2018-04-16 09:48:57 +0100 |
commit | 748a2f2b542fed2cb8ab7d1792cb874ce7423a61 (patch) | |
tree | 47a281d89c47e9e1751e450429784430ff2049a7 /app/assets/javascripts/ide/components/file_finder | |
parent | c3e26860be156314e733a6dfb986c91fc55766f5 (diff) | |
download | gitlab-ce-748a2f2b542fed2cb8ab7d1792cb874ce7423a61.tar.gz |
Added fuzzy file finder to web IDE
Closes #44841
Diffstat (limited to 'app/assets/javascripts/ide/components/file_finder')
-rw-r--r-- | app/assets/javascripts/ide/components/file_finder/index.vue | 100 | ||||
-rw-r--r-- | app/assets/javascripts/ide/components/file_finder/item.vue | 36 |
2 files changed, 136 insertions, 0 deletions
diff --git a/app/assets/javascripts/ide/components/file_finder/index.vue b/app/assets/javascripts/ide/components/file_finder/index.vue new file mode 100644 index 00000000000..ebcd6f7592b --- /dev/null +++ b/app/assets/javascripts/ide/components/file_finder/index.vue @@ -0,0 +1,100 @@ +<script> +import { mapGetters, mapState } from 'vuex'; +import fuzzaldrinPlus from 'fuzzaldrin-plus'; +import VirtualList from 'vue-virtual-scroll-list'; +import Item from './item.vue'; + +export default { + components: { + Item, + VirtualList, + }, + data() { + return { + searchText: '', + }; + }, + computed: { + ...mapGetters(['allBlobs']), + ...mapState(['loading']), + filteredBlobs() { + const searchText = this.searchText.trim(); + + if (searchText === '') return this.allBlobs; + + return fuzzaldrinPlus.filter(this.allBlobs, searchText, { + key: 'path', + }); + }, + listShowCount() { + if (this.filteredBlobs.length === 0) return 1; + + return this.filteredBlobs.length > 5 ? 5 : this.filteredBlobs.length; + }, + listHeight() { + return this.listShowCount > 1 ? 55 : 33; + }, + }, + mounted() { + this.$refs.searchInput.focus(); + }, +}; +</script> + +<template> + <div class="dropdown-menu diff-file-changes ide-file-finder" style="display: block;"> + <div class="dropdown-input"> + <input + type="search" + class="dropdown-input-field" + placeholder="Search files" + autocomplete="off" + v-model="searchText" + ref="searchInput" + /> + <i + aria-hidden="true" + class="fa fa-search dropdown-input-search" + ></i> + </div> + <div> + <virtual-list + :size="listHeight" + :remain="listShowCount" + wtag="ul" + > + <template v-if="filteredBlobs.length"> + <li + v-for="file in filteredBlobs" + :key="file.key" + > + <item + :file="file" + /> + </li> + </template> + <li + v-else + class="dropdown-menu-empty-itemhidden" + > + <a href=""> + <template v-if="loading"> + Loading... + </template> + <template v-else> + No files found. + </template> + </a> + </li> + </virtual-list> + </div> + </div> +</template> + +<style> +.ide-file-finder { + top: 100px; + left: 50%; + transform: translateX(-50%); +} +</style> diff --git a/app/assets/javascripts/ide/components/file_finder/item.vue b/app/assets/javascripts/ide/components/file_finder/item.vue new file mode 100644 index 00000000000..482bfb96d93 --- /dev/null +++ b/app/assets/javascripts/ide/components/file_finder/item.vue @@ -0,0 +1,36 @@ +<script> +import FileIcon from '../../../vue_shared/components/file_icon.vue'; + +export default { + components: { + FileIcon, + }, + props: { + file: { + type: Object, + required: true, + }, + }, +}; +</script> + +<template> + <a + href="" + class="diff-changed-file" + > + <file-icon + :file-name="file.name" + :size="16" + css-classes="diff-file-changed-icon append-right-8" + /> + <span class="diff-changed-file-content append-right-8"> + <strong class="diff-changed-file-name"> + {{ file.name }} + </strong> + <span class="diff-changed-file-path prepend-top-5"> + {{ file.path }} + </span> + </span> + </a> +</template> |