@@ -12,11 +12,14 @@ const searchResults = useTemplateRef('searchResults');
1212const searchQuery = ref (' ' );
1313const allFiles = ref <string []>([]);
1414const selectedIndex = ref (0 );
15+ const isLoadingFileList = ref (false );
16+ const hasLoadedFileList = ref (false );
1517
1618const props = defineProps ({
1719 repoLink: {type: String , required: true },
1820 treePath: {type: String , required: true },
1921 currentRefNameSubURL: {type: String , required: true },
22+ noResultsText: {type: String , required: true },
2023});
2124
2225const store = createViewFileTreeStore (props );
@@ -26,7 +29,7 @@ const filteredFiles = computed(() => {
2629 return filterRepoFilesWeighted (allFiles .value , searchQuery .value );
2730});
2831
29- const treeLink = computed (() => ` ${props .repoLink }/src/${props .currentRefNameSubURL } ` );
32+ const treeLink = computed (() => ` ${props .repoLink }/src/${pathEscapeSegments ( props .currentRefNameSubURL ) } ` );
3033
3134let searchInputElement: HTMLInputElement | null = null ;
3235
@@ -90,19 +93,33 @@ const handleClickOutside = (e: MouseEvent) => {
9093 }
9194};
9295
96+ const loadFileListForSearch = async () => {
97+ if (hasLoadedFileList .value || isLoadingFileList .value ) return ;
98+
99+ isLoadingFileList .value = true ;
100+ try {
101+ const treeListUrl = elRoot .value .closest (' #view-file-tree' )?.getAttribute (' data-tree-list-url' );
102+ if (treeListUrl ) {
103+ const response = await GET (treeListUrl );
104+ allFiles .value = await response .json ();
105+ hasLoadedFileList .value = true ;
106+ }
107+ } finally {
108+ isLoadingFileList .value = false ;
109+ }
110+ };
111+
112+ const handleSearchFocus = () => {
113+ loadFileListForSearch ();
114+ };
115+
93116onMounted (async () => {
94117 store .rootFiles = await store .loadChildren (' ' , props .treePath );
95118 elRoot .value .closest (' .is-loading' )?.classList ?.remove (' is-loading' );
96119
97- // Load all files for search
98- const treeListUrl = elRoot .value .closest (' #view-file-tree' )?.getAttribute (' data-tree-list-url' );
99- if (treeListUrl ) {
100- const response = await GET (treeListUrl );
101- allFiles .value = await response .json ();
102- }
103-
104120 searchInputElement = document .querySelector (' #file-tree-search' );
105121 if (searchInputElement ) {
122+ searchInputElement .addEventListener (' focus' , handleSearchFocus );
106123 searchInputElement .addEventListener (' input' , handleSearchInput );
107124 searchInputElement .addEventListener (' keydown' , handleKeyDown );
108125 document .addEventListener (' click' , handleClickOutside );
@@ -129,6 +146,7 @@ watch(searchQuery, async () => {
129146
130147onUnmounted (() => {
131148 if (searchInputElement ) {
149+ searchInputElement .removeEventListener (' focus' , handleSearchFocus );
132150 searchInputElement .removeEventListener (' input' , handleSearchInput );
133151 searchInputElement .removeEventListener (' keydown' , handleKeyDown );
134152 document .removeEventListener (' click' , handleClickOutside );
@@ -168,7 +186,7 @@ function handleSearchResultClick(filePath: string) {
168186 <div class =" file-tree-no-results-content" >
169187 <!-- eslint-disable-next-line vue/no-v-html -->
170188 <span v-html =" svg('octicon-search', 24)" />
171- <span >No matching files found </span >
189+ <span >{{ props.noResultsText }} </span >
172190 </div >
173191 </div >
174192 </Teleport >
0 commit comments