diff --git a/components/dashboard/src/admin/WorkspacesSearch.tsx b/components/dashboard/src/admin/WorkspacesSearch.tsx
index 74fc1a4b868748..93aabaefe8bf95 100644
--- a/components/dashboard/src/admin/WorkspacesSearch.tsx
+++ b/components/dashboard/src/admin/WorkspacesSearch.tsx
@@ -89,7 +89,7 @@ export function WorkspaceSearch(props: Props) {
- ke.key === 'Enter' && search() } onChange={(v) => { setSearchTerm(v.target.value) }} />
+ ke.key === 'Enter' && search() } onChange={(v) => { setSearchTerm(v.target.value) }} />
@@ -125,4 +125,4 @@ function WorkspaceEntry(p: { ws: WorkspaceAndInstance }) {
;
-}
\ No newline at end of file
+}
diff --git a/components/gitpod-db/src/typeorm/workspace-db-impl.ts b/components/gitpod-db/src/typeorm/workspace-db-impl.ts
index 42ab7a7b8f650d..7aa8fe21450db5 100644
--- a/components/gitpod-db/src/typeorm/workspace-db-impl.ts
+++ b/components/gitpod-db/src/typeorm/workspace-db-impl.ts
@@ -698,14 +698,22 @@ export abstract class AbstractTypeORMWorkspaceDBImpl extends AbstractWorkspaceDB
public async findAllWorkspaceAndInstances(offset: number, limit: number, orderBy: keyof WorkspaceAndInstance, orderDir: "ASC" | "DESC", ownerId?: string, searchTerm?: string): Promise<{ total: number, rows: WorkspaceAndInstance[] }> {
- let joinConditions = [];
- let joinConditionParams: any = {};
+ let whereConditions = ['wsi2.id IS NULL'];
+ let whereConditionParams: any = {};
+
if (!!ownerId) {
- joinConditions.push("ws.ownerId = :ownerId");
- joinConditionParams.ownerId = ownerId;
+ // If an owner id is provided only search for workspaces belonging to that user.
+ whereConditions.push("ws.ownerId = :ownerId");
+ whereConditionParams.ownerId = ownerId;
}
+
if (!!searchTerm) {
- joinConditions.push(`ws.contextURL LIKE '%${searchTerm}%'`);
+ // If a search term is provided perform a wildcard search in the context url or exact match on the workspace id (aka workspace name) or the instance id.
+ whereConditions.push([
+ `ws.contextURL LIKE '%${searchTerm}%'`,
+ `ws.id = '${searchTerm}'`,
+ `wsi.id = '${searchTerm}'`
+ ].join(' OR '))
}
let orderField: string = orderBy;
@@ -731,7 +739,7 @@ export abstract class AbstractTypeORMWorkspaceDBImpl extends AbstractWorkspaceDB
'wsi2.workspaceId = ws.id',
'(wsi.creationTime < wsi2.creationTime OR (wsi.creationTime = wsi2.creationTime AND wsi.id < wsi2.id))'
].join(' AND '))
- .where([ ... joinConditions, 'wsi2.id IS NULL' ].join(' AND '), joinConditionParams)
+ .where(whereConditions.join(' AND '), whereConditionParams)
.orderBy(orderField, orderDir)
.take(limit)
.skip(offset);
diff --git a/components/gitpod-db/src/workspace-db.spec.db.ts b/components/gitpod-db/src/workspace-db.spec.db.ts
index f3ce4caf833225..8d5e68bf0ede16 100644
--- a/components/gitpod-db/src/workspace-db.spec.db.ts
+++ b/components/gitpod-db/src/workspace-db.spec.db.ts
@@ -301,5 +301,48 @@ import { DBWorkspaceInstance } from './typeorm/entity/db-workspace-instance';
expect(workspaceAndInstance.instanceId).to.eq(this.wsi2.id)
});
}
+
+ @test(timeout(10000))
+ public async testFindAllWorkspaceAndInstances_workspaceId() {
+ await this.db.transaction(async db => {
+ await Promise.all([
+ db.store(this.ws),
+ db.storeInstance(this.wsi1),
+ db.store(this.ws2),
+ db.storeInstance(this.ws2i1),
+ ]);
+ const dbResult = await db.findAllWorkspaceAndInstances(0, 10, "workspaceId", "DESC", undefined, this.ws2.id);
+ // It should only find one workspace instance
+ expect(dbResult.total).to.eq(1);
+
+ // It should find the workspace with the queried id
+ const workspaceAndInstance = dbResult.rows[0]
+ expect(workspaceAndInstance.workspaceId).to.eq(this.ws2.id)
+ });
+ }
+
+ @test(timeout(10000))
+ public async testFindAllWorkspaceAndInstances_instanceId() {
+ await this.db.transaction(async db => {
+ await Promise.all([
+ db.store(this.ws),
+ db.storeInstance(this.wsi1),
+ db.storeInstance(this.wsi2),
+ db.store(this.ws2),
+ db.storeInstance(this.ws2i1),
+ ]);
+ const dbResult = await db.findAllWorkspaceAndInstances(0, 10, "instanceId", "DESC", undefined, this.wsi1.id);
+
+ // It should only find one workspace instance
+ expect(dbResult.total).to.eq(1);
+
+ // It should find the workspace with the queried id
+ const workspaceAndInstance = dbResult.rows[0]
+ expect(workspaceAndInstance.workspaceId).to.eq(this.ws.id)
+
+ // It should select the workspace instance that was queried, not the most recent one
+ expect(workspaceAndInstance.instanceId).to.eq(this.wsi1.id)
+ });
+ }
}
module.exports = new WorkspaceDBSpec()