diff --git a/components/dashboard/src/components/RepositoryFinder.tsx b/components/dashboard/src/components/RepositoryFinder.tsx
index 352c9560dc678b..21fadab0cb42ea 100644
--- a/components/dashboard/src/components/RepositoryFinder.tsx
+++ b/components/dashboard/src/components/RepositoryFinder.tsx
@@ -6,7 +6,6 @@
import { User } from "@gitpod/gitpod-protocol";
import React, { useContext, useEffect, useState } from "react";
-import { Link } from "react-router-dom";
import { getGitpodService } from "../service/service";
import { UserContext } from "../user-context";
@@ -14,7 +13,7 @@ type SearchResult = string;
type SearchData = SearchResult[];
const LOCAL_STORAGE_KEY = 'open-in-gitpod-search-data';
-const MAX_DISPLAYED_ITEMS = 15;
+const MAX_DISPLAYED_ITEMS = 20;
export default function RepositoryFinder(props: { initialQuery?: string }) {
const { user } = useContext(UserContext);
@@ -38,6 +37,10 @@ export default function RepositoryFinder(props: { initialQuery?: string }) {
}
}
+ useEffect(() => {
+ search('');
+ }, []);
+
// Up/Down keyboard navigation between results
const onKeyDown = (event: React.KeyboardEvent) => {
if (!selectedSearchResult) {
@@ -81,18 +84,9 @@ export default function RepositoryFinder(props: { initialQuery?: string }) {
- search(e.target.value)} onKeyDown={onKeyDown} />
+ search(e.target.value)} onKeyDown={onKeyDown} />
- {searchQuery === '' && searchResults.length === 0 &&
-
- Paste a
repository context URL, or start typing to see suggestions from:
-
- - Your recent repositories
- - Your repositories from connected integrations
- - Example repositories
-
-
}
{searchResults.slice(0, MAX_DISPLAYED_ITEMS).map((result, index) =>
setSelectedSearchResult(result)}>
{searchQuery.length < 2
@@ -157,10 +151,6 @@ async function actuallyRefreshSearchData(query: string, user: User | undefined):
}
async function findResults(query: string, onResults: (results: string[]) => void) {
- if (!query) {
- onResults([]);
- return;
- }
const searchData = loadSearchData();
try {
// If the query is a URL, and it's not present in the proposed results, "artificially" add it here.
diff --git a/components/server/src/workspace/gitpod-server-impl.ts b/components/server/src/workspace/gitpod-server-impl.ts
index 8982e5fed407a6..78f386ecd8de90 100644
--- a/components/server/src/workspace/gitpod-server-impl.ts
+++ b/components/server/src/workspace/gitpod-server-impl.ts
@@ -1029,7 +1029,7 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable {
public async getSuggestedContextURLs(ctx: TraceContext): Promise {
const user = this.checkUser("getSuggestedContextURLs");
- const suggestions: string[] = [];
+ const suggestions: Array<{ url: string, lastUse?: string }> = [];
const logCtx: LogContext = { userId: user.id };
// Fetch all data sources in parallel for maximum speed (don't await in this scope before `Promise.allSettled(promises)` below!)
@@ -1037,7 +1037,7 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable {
// Example repositories
promises.push(this.getFeaturedRepositories(ctx).then(exampleRepos => {
- exampleRepos.forEach(r => suggestions.push(r.url));
+ exampleRepos.forEach(r => suggestions.push({ url: r.url }));
}).catch(error => {
log.error(logCtx, 'Could not get example repositories', error);
}));
@@ -1046,7 +1046,7 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable {
promises.push(this.getAuthProviders(ctx).then(authProviders => Promise.all(authProviders.map(async (p) => {
try {
const userRepos = await this.getProviderRepositoriesForUser(ctx, { provider: p.host });
- userRepos.forEach(r => suggestions.push(r.cloneUrl.replace(/\.git$/, '')));
+ userRepos.forEach(r => suggestions.push({ url: r.cloneUrl.replace(/\.git$/, '') }));
} catch (error) {
log.debug(logCtx, 'Could not get user repositories from App for ' + p.host, error);
}
@@ -1064,7 +1064,7 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable {
return;
}
const userRepos = await services.repositoryProvider.getUserRepos(user);
- userRepos.forEach(r => suggestions.push(r.replace(/\.git$/, '')));
+ userRepos.forEach(r => suggestions.push({ url: r.replace(/\.git$/, '') }));
} catch (error) {
log.debug(logCtx, 'Could not get user repositories from host ' + p.host, error);
}
@@ -1077,7 +1077,8 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable {
workspaces.forEach(ws => {
const repoUrl = Workspace.getFullRepositoryUrl(ws.workspace);
if (repoUrl) {
- suggestions.push(repoUrl);
+ const lastUse = WorkspaceInfo.lastActiveISODate(ws);
+ suggestions.push({ url: repoUrl, lastUse });
}
});
}).catch(error => {
@@ -1088,14 +1089,25 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable {
const uniqueURLs = new Set();
return suggestions
- .sort((a, b) => a.toLowerCase() > b.toLowerCase() ? 1 : -1)
- .filter(r => {
- if (uniqueURLs.has(r)) {
+ .sort((a, b) => {
+ // Most recently used first
+ if (b.lastUse || a.lastUse) {
+ const la = a.lastUse || '';
+ const lb = b.lastUse || '';
+ return la < lb ? 1 : (la === lb ? 0 : -1);
+ }
+ // Otherwise, alphasort
+ const ua = a.url.toLowerCase();
+ const ub = b.url.toLowerCase();
+ return ua > ub ? 1 : (ua === ub ? 0 : -1);
+ })
+ .filter(s => {
+ if (uniqueURLs.has(s.url)) {
return false;
}
- uniqueURLs.add(r);
+ uniqueURLs.add(s.url);
return true;
- });
+ }).map(s => s.url);
}
public async setWorkspaceTimeout(ctx: TraceContext, workspaceId: string, duration: WorkspaceTimeoutDuration): Promise {