Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ object DashboardResource {
searchQueryParams: SearchQueryParams
): List[OrderField[_]] = {
// Regex pattern to extract column name and order direction
val pattern = "(Name|CreateTime|EditTime)(Asc|Desc)".r
val pattern = "(Name|CreateTime|EditTime|ExecutionTime)(Asc|Desc)".r

searchQueryParams.orderBy match {
case pattern(column, order) =>
Expand All @@ -154,7 +154,7 @@ object DashboardResource {
case Some(value) =>
List(order match {
case "Asc" => value.asc()
case "Desc" => value.desc()
case "Desc" => value.desc().nullsLast()
})
case None => List()
}
Expand All @@ -165,10 +165,11 @@ object DashboardResource {
// Helper method to map column names to actual database fields based on resource type
private def getColumnField(columnName: String): Option[Field[_]] = {
Option(columnName match {
case "Name" => UnifiedResourceSchema.resourceNameField
case "CreateTime" => UnifiedResourceSchema.resourceCreationTimeField
case "EditTime" => UnifiedResourceSchema.resourceLastModifiedTimeField
case _ => null // Default case for unmatched resource types or column names
case "Name" => UnifiedResourceSchema.resourceNameField
case "CreateTime" => UnifiedResourceSchema.resourceCreationTimeField
case "EditTime" => UnifiedResourceSchema.resourceLastModifiedTimeField
case "ExecutionTime" => UnifiedResourceSchema.resourceExecutionTimeField
case _ => null // Default case for unmatched resource types or column names
})
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ object UnifiedResourceSchema {
private val resourceCreationTimeAlias = "resourceCreationTime"
private val resourceOwnerIdAlias = "resourceOwnerId"
private val resourceLastModifiedTimeAlias = "resourceLastModifiedTime"
private val resourceExecutionTimeAlias = "resourceExecutionTime"

// Use the alias variables to create fields
val resourceTypeField: Field[_] = DSL.field(DSL.name(resourceTypeAlias))
Expand All @@ -45,6 +46,7 @@ object UnifiedResourceSchema {
val resourceCreationTimeField: Field[_] = DSL.field(DSL.name(resourceCreationTimeAlias))
val resourceOwnerIdField: Field[_] = DSL.field(DSL.name(resourceOwnerIdAlias))
val resourceLastModifiedTimeField: Field[_] = DSL.field(DSL.name(resourceLastModifiedTimeAlias))
val resourceExecutionTimeField: Field[_] = DSL.field(DSL.name(resourceExecutionTimeAlias))

def context =
SqlServer
Expand All @@ -57,6 +59,7 @@ object UnifiedResourceSchema {
description: Field[String] = DSL.inline(""),
creationTime: Field[Timestamp] = DSL.cast(null, classOf[Timestamp]),
lastModifiedTime: Field[Timestamp] = DSL.cast(null, classOf[Timestamp]),
executionTime: Field[Timestamp] = DSL.cast(null, classOf[Timestamp]),
ownerId: Field[Integer] = DSL.cast(null, classOf[Integer]),
wid: Field[Integer] = DSL.cast(null, classOf[Integer]),
workflowUserAccess: Field[PrivilegeEnum] = DSL.castNull(classOf[PrivilegeEnum]),
Expand All @@ -82,6 +85,7 @@ object UnifiedResourceSchema {
description -> description.as(resourceDescriptionAlias),
creationTime -> creationTime.as(resourceCreationTimeAlias),
lastModifiedTime -> lastModifiedTime.as(resourceLastModifiedTimeAlias),
executionTime -> executionTime.as(resourceExecutionTimeAlias),
ownerId -> ownerId.as(resourceOwnerIdAlias),
wid -> wid.as("wid"),
workflowUserAccess -> workflowUserAccess.as("workflow_privilege"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@ object WorkflowSearchQueryBuilder extends SearchQueryBuilder {
creationTime = WORKFLOW.CREATION_TIME,
wid = WORKFLOW.WID,
lastModifiedTime = WORKFLOW.LAST_MODIFIED_TIME,
executionTime = DSL.field(
DSL
.select(DSL.max(WORKFLOW_EXECUTIONS.STARTING_TIME))
.from(WORKFLOW_EXECUTIONS)
.join(WORKFLOW_VERSION)
.on(WORKFLOW_EXECUTIONS.VID.eq(WORKFLOW_VERSION.VID))
.where(WORKFLOW_VERSION.WID.eq(WORKFLOW.WID))
),
workflowUserAccess = WORKFLOW_USER_ACCESS.PRIVILEGE,
uid = WORKFLOW_OF_USER.UID,
ownerId = WORKFLOW_OF_USER.UID,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -780,4 +780,30 @@ class WorkflowResourceSpec
assert(resources.results(2).workflow.get.workflow.getName == "test_workflow1")
}

it should "order workflow by execution time correctly" in {
// Create several resources with different names (no execution times are set, but the SQL query should parse correctly)
workflowResource.persistWorkflow(testWorkflow1, sessionUser1)
workflowResource.persistWorkflow(testWorkflow3, sessionUser1)
workflowResource.persistWorkflow(testWorkflow2, sessionUser1)

// Retrieve resources ordered by execution time ascending
var resources =
dashboardResource.searchAllResourcesCall(
sessionUser1,
SearchQueryParams(resourceType = "workflow", orderBy = "ExecutionTimeAsc")
)

// Execution times are null so order is not guaranteed, but we verify it returns 3 results
assert(resources.results.length == 3)

// Retrieve resources ordered by execution time descending
resources = dashboardResource.searchAllResourcesCall(
sessionUser1,
SearchQueryParams(resourceType = "workflow", orderBy = "ExecutionTimeDesc")
)

// Verify it returns 3 results
assert(resources.results.length == 3)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,13 @@
By Create Time
</button>
</li>
<li nz-menu-item>
<button
(click)="execSort()"
nz-button>
By Execution Time
</button>
</li>
<li nz-menu-item>
<button
(click)="ascSort()"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,11 @@ describe("SortButtonComponent", () => {
expect(component.sortMethod).toBe(SortMethod.NameDesc);
expect(emitSpy).toHaveBeenCalledWith(SortMethod.NameDesc);
});

it("should handle execSort() correctly", () => {
const emitSpy = vi.spyOn(component.sortMethodChange, "emit");
component.execSort();
expect(component.sortMethod).toBe(SortMethod.ExecutionTimeDesc);
expect(emitSpy).toHaveBeenCalledWith(SortMethod.ExecutionTimeDesc);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,9 @@ export class SortButtonComponent {
this.sortMethod = SortMethod.NameDesc;
this.sortMethodChange.emit(this.sortMethod);
}

public execSort(): void {
this.sortMethod = SortMethod.ExecutionTimeDesc;
this.sortMethodChange.emit(this.sortMethod);
}
}
1 change: 1 addition & 0 deletions frontend/src/app/dashboard/type/sort-method.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ export enum SortMethod {
NameDesc,
CreateTimeDesc,
EditTimeDesc,
ExecutionTimeDesc,
}