diff --git a/src/core/Elsa.Core/Persistence/Specifications/WorkflowInstances/WorkflowInstanceSpecificationExtensions.cs b/src/core/Elsa.Core/Persistence/Specifications/WorkflowInstances/WorkflowInstanceSpecificationExtensions.cs index 7d2f40db3..0324a3338 100644 --- a/src/core/Elsa.Core/Persistence/Specifications/WorkflowInstances/WorkflowInstanceSpecificationExtensions.cs +++ b/src/core/Elsa.Core/Persistence/Specifications/WorkflowInstances/WorkflowInstanceSpecificationExtensions.cs @@ -12,8 +12,9 @@ namespace Elsa.Persistence.Specifications.WorkflowInstances public static ISpecification WithContextId(this ISpecification specification, string contextId) => specification.And(new WorkflowInstanceContextIdMatchSpecification(typeof(TContextType), contextId)); public static ISpecification WithContext(this ISpecification specification, string contextType) => specification.And(new WorkflowInstanceContextMatchSpecification(contextType)); public static ISpecification WithContext(this ISpecification specification, Type contextType) => specification.And(new WorkflowInstanceContextMatchSpecification(contextType)); - public static ISpecification WithContextd(this ISpecification specification) => specification.And(new WorkflowInstanceContextMatchSpecification(typeof(TContextType))); + public static ISpecification WithContextId(this ISpecification specification) => specification.And(new WorkflowInstanceContextMatchSpecification(typeof(TContextType))); public static ISpecification WithStatus(this ISpecification specification, WorkflowStatus status) => specification.And(new WorkflowStatusSpecification(status)); + public static ISpecification WithSearchTerm(this ISpecification specification, string searchTerm) => specification.And(new WorkflowSearchTermSpecification(searchTerm)); } } diff --git a/src/core/Elsa.Core/Persistence/Specifications/WorkflowInstances/WorkflowSearchTermSpecification.cs b/src/core/Elsa.Core/Persistence/Specifications/WorkflowInstances/WorkflowSearchTermSpecification.cs new file mode 100644 index 000000000..8202ce92e --- /dev/null +++ b/src/core/Elsa.Core/Persistence/Specifications/WorkflowInstances/WorkflowSearchTermSpecification.cs @@ -0,0 +1,13 @@ +using System; +using System.Linq.Expressions; +using Elsa.Models; + +namespace Elsa.Persistence.Specifications.WorkflowInstances +{ + public class WorkflowSearchTermSpecification : Specification + { + public string SearchTerm { get; set; } + public WorkflowSearchTermSpecification(string searchTerm) => SearchTerm = searchTerm; + public override Expression> ToExpression() => x => x.Name!.Contains(SearchTerm) || x.Id.Contains(SearchTerm) || x.ContextId!.Contains(SearchTerm); + } +} \ No newline at end of file diff --git a/src/designer/elsa-workflows-studio/src/components/controls/elsa-pager/elsa-pager.tsx b/src/designer/elsa-workflows-studio/src/components/controls/elsa-pager/elsa-pager.tsx index 1ed25ef22..c131a8a99 100644 --- a/src/designer/elsa-workflows-studio/src/components/controls/elsa-pager/elsa-pager.tsx +++ b/src/designer/elsa-workflows-studio/src/components/controls/elsa-pager/elsa-pager.tsx @@ -42,7 +42,7 @@ export class ElsaPager { const from = page * pageSize + 1; const to = Math.min(from + pageSize, totalCount); - const pageCount = Math.round(((totalCount - 1) / pageSize) + 1); + const pageCount = Math.round(((totalCount - 1) / pageSize) + 0.5); const maxPageButtons = 10; const fromPage = Math.max(0, page - maxPageButtons / 2); diff --git a/src/designer/elsa-workflows-studio/src/components/screens/workflow-instances-list/elsa-workflow-instances-list-screen/elsa-workflow-instances-list-screen.tsx b/src/designer/elsa-workflows-studio/src/components/screens/workflow-instances-list/elsa-workflow-instances-list-screen/elsa-workflow-instances-list-screen.tsx index 6d4c440fb..e3948b69a 100644 --- a/src/designer/elsa-workflows-studio/src/components/screens/workflow-instances-list/elsa-workflow-instances-list-screen/elsa-workflow-instances-list-screen.tsx +++ b/src/designer/elsa-workflows-studio/src/components/screens/workflow-instances-list/elsa-workflow-instances-list-screen/elsa-workflow-instances-list-screen.tsx @@ -23,7 +23,8 @@ export class ElsaWorkflowInstancesListScreen { @State() selectedWorkflowInstanceIds: Array = []; @State() selectAllChecked: boolean; @State() page: number = 0; - @State() pageSize: number = 25; + @State() pageSize: number = 15; + @State() searchTerm?: string; confirmDialog: HTMLElsaConfirmDialogElement; @@ -42,7 +43,7 @@ export class ElsaWorkflowInstancesListScreen { this.selectedWorkflowStatus = query.status; this.selectedOrderBy = query.orderBy ?? OrderBy.Started; this.page = !!query.page ? parseInt(query.page) : 0; - this.pageSize = !!query.pageSize ? parseInt(query.pageSize) : 25; + this.pageSize = !!query.pageSize ? parseInt(query.pageSize) : 15; } async loadWorkflowBlueprints() { @@ -54,7 +55,7 @@ export class ElsaWorkflowInstancesListScreen { async loadWorkflowInstances() { const elsaClient = this.createClient(); - this.workflowInstances = await elsaClient.workflowInstancesApi.list(this.page, this.pageSize, this.selectedWorkflowId, this.selectedWorkflowStatus, this.selectedOrderBy); + this.workflowInstances = await elsaClient.workflowInstancesApi.list(this.page, this.pageSize, this.selectedWorkflowId, this.selectedWorkflowStatus, this.selectedOrderBy, this.searchTerm); } createClient() { @@ -77,11 +78,11 @@ export class ElsaWorkflowInstancesListScreen { if (!!orderBy) filters['orderBy'] = orderBy; - - if(!!this.page) + + if (!!this.page) filters['page'] = this.page.toString(); - if(!!this.pageSize) + if (!!this.pageSize) filters['pageSize'] = this.pageSize.toString(); const queryString = collection.map(filters, (v, k) => `${k}=${v}`).join('&'); @@ -108,7 +109,7 @@ export class ElsaWorkflowInstancesListScreen { async routeChanged(e: LocationSegments) { debugger; - + if (e.pathname.toLowerCase().indexOf('workflow-instances') < 0) return; @@ -170,6 +171,16 @@ export class ElsaWorkflowInstancesListScreen { } } + async onSearch(e: Event) { + e.preventDefault(); + const form = e.currentTarget as HTMLFormElement; + const formData = new FormData(form); + const searchTerm: FormDataEntryValue = formData.get('searchTerm'); + + this.searchTerm = searchTerm.toString(); + await this.loadWorkflowInstances(); + } + render() { const workflowInstances = this.workflowInstances.items; const workflowBlueprints = this.workflowBlueprints; @@ -198,6 +209,28 @@ export class ElsaWorkflowInstancesListScreen { return (
+ +
+
+
+
this.onSearch(e)}> + +
+
+ + + +
+ +
+
+
+
+
+
{this.renderBulkActions()} diff --git a/src/server/Elsa.Server.Api/Endpoints/WorkflowInstances/List.cs b/src/server/Elsa.Server.Api/Endpoints/WorkflowInstances/List.cs index a37fcc80c..08a254b00 100644 --- a/src/server/Elsa.Server.Api/Endpoints/WorkflowInstances/List.cs +++ b/src/server/Elsa.Server.Api/Endpoints/WorkflowInstances/List.cs @@ -61,8 +61,8 @@ namespace Elsa.Server.Api.Endpoints.WorkflowInstances if (workflowStatus != null) specification = specification.WithStatus(workflowStatus.Value); - if (!string.IsNullOrWhiteSpace(searchTerm)) - specification = specification.WithWorkflowName(searchTerm); + if (!string.IsNullOrWhiteSpace(searchTerm)) + specification = specification.WithSearchTerm(searchTerm); var orderBySpecification = default(OrderBy);