Completed missing bulk actions functionalities

This commit is contained in:
Gürkan Güran 2023-04-20 09:59:09 +02:00
parent 169443bd0d
commit 6cbad8b5d7
6 changed files with 104 additions and 20 deletions

View file

@ -92,4 +92,12 @@ export class DefaultModalActions {
isPrimary: true,
onClick: handler
});
public static Yes = (handler?: (args: ModalActionClickArgs) => void): ModalActionDefinition => ({
text: 'Yes',
name: 'Yes',
type: ModalActionType.Button,
isDangerous: true,
onClick: handler
});
}

View file

@ -83,6 +83,9 @@ export class WorkflowDefinitionBrowser {
}
private onDeleteManyClick = async () => {
if(this.selectedWorkflowDefinitionIds.length == 0)
return;
this.modalDialogService.show(
() => DefaultContents.Warning("Are you sure you want to delete selected workflow definitions?"),
{
@ -96,6 +99,9 @@ export class WorkflowDefinitionBrowser {
};
private onPublishManyClick = async () => {
if(this.selectedWorkflowDefinitionIds.length == 0)
return;
this.modalDialogService.show(
() => DefaultContents.Warning("Are you sure you want to publish selected workflow definitions?"),
{
@ -108,6 +114,9 @@ export class WorkflowDefinitionBrowser {
};
private onUnpublishManyClick = async () => {
if(this.selectedWorkflowDefinitionIds.length == 0)
return;
this.modalDialogService.show(
() => DefaultContents.Warning("Are you sure you want to unpublish selected workflow definitions?"),
{

View file

@ -12,6 +12,7 @@ import {getSubStatusColor, updateSelectedWorkflowInstances} from "../services/ut
import {formatTimestamp} from "../../../utils";
import {DeleteIcon, EditIcon} from "../../../components/icons/tooling";
import {PagerData} from "../../../components/shared/pager/pager";
import {DefaultContents, DefaultModalActions, ModalDialogService, ModalType} from '../../../components/shared/modal-dialog';
@Component({
tag: 'elsa-workflow-instance-browser',
@ -25,6 +26,7 @@ export class WorkflowInstanceBrowser {
private readonly workflowInstancesApi: WorkflowInstancesApi;
private readonly workflowDefinitionsApi: WorkflowDefinitionsApi;
private readonly modalDialogService: ModalDialogService;
private selectAllCheckbox: HTMLInputElement;
private publishedOrLatestWorkflows: Array<WorkflowDefinitionSummary> = [];
@ -33,6 +35,7 @@ export class WorkflowInstanceBrowser {
constructor() {
this.workflowInstancesApi = Container.get(WorkflowInstancesApi);
this.workflowDefinitionsApi = Container.get(WorkflowDefinitionsApi);
this.modalDialogService = Container.get(ModalDialogService);
}
@Event() public workflowInstanceSelected: EventEmitter<WorkflowInstanceSummary>;
@ -102,7 +105,9 @@ export class WorkflowInstanceBrowser {
this.selectedWorkflowDefinitionId = undefined
await this.loadWorkflowInstances();
}
},
onBulkDelete: this.onDeleteManyClick,
onBulkCancel: this.onCancelManyClick
};
return (
@ -182,6 +187,36 @@ export class WorkflowInstanceBrowser {
);
}
private onDeleteManyClick = async () => {
if(this.selectedWorkflowInstanceIds.length == 0)
return;
this.modalDialogService.show(
() => DefaultContents.Warning("Are you sure you want to delete selected workflow instances?"),
{
actions: [DefaultModalActions.Delete(async () => {
await this.workflowInstancesApi.deleteMany({workflowInstanceIds: this.selectedWorkflowInstanceIds});
await this.loadWorkflowInstances();
}), DefaultModalActions.Cancel()],
modalType: ModalType.Confirmation
});
};
private onCancelManyClick = async () => {
if(this.selectedWorkflowInstanceIds.length == 0)
return;
this.modalDialogService.show(
() => DefaultContents.Warning("Are you sure you want to cancel selected workflow instances?"),
{
actions: [DefaultModalActions.Yes(async () => {
await this.workflowInstancesApi.cancelMany({workflowInstanceIds: this.selectedWorkflowInstanceIds});
await this.loadWorkflowInstances();
}), DefaultModalActions.Cancel()],
modalType: ModalType.Confirmation
});
};
private resetPagination = () => {
this.currentPage = 0;
this.selectedWorkflowInstanceIds = [];

View file

@ -4,7 +4,7 @@ import {OrderBy, WorkflowStatus, WorkflowSubStatus} from "../../../models";
import {DropdownButtonItem, DropdownButtonOrigin} from "../../../components/shared/dropdown-button/models";
import {BulkActionsIcon, OrderByIcon, PageSizeIcon, WorkflowIcon, WorkflowStatusIcon} from "../../../components/icons/tooling";
export interface FilterProps {
export interface FilterProps extends BulkActionsProps {
pageSizeFilter: PageSizeFilterProps;
workflowFilter: WorkflowFilterProps;
statusFilter: StatusFilterProps;
@ -13,6 +13,11 @@ export interface FilterProps {
resetFilter: () => void;
}
export interface BulkActionsProps {
onBulkDelete: () => void;
onBulkCancel: () => void;
}
export interface PageSizeFilterProps {
selectedPageSize: number;
onChange: (pageSize: number) => void;
@ -39,11 +44,11 @@ export interface OrderByFilterProps {
onChange: (orderBy: OrderBy) => void;
}
export const Filter: FunctionalComponent<FilterProps> = ({pageSizeFilter, workflowFilter, statusFilter, subStatusFilter, orderByFilter, resetFilter}) => {
export const Filter: FunctionalComponent<FilterProps> = ({pageSizeFilter, workflowFilter, statusFilter, subStatusFilter, orderByFilter, resetFilter, onBulkDelete, onBulkCancel}) => {
return <div class="p-8 flex content-end justify-right bg-white space-x-4">
<div class="flex-shrink-0">
<BulkActions/>
<BulkActions onBulkDelete={onBulkDelete} onBulkCancel={onBulkCancel} />
</div>
<div class="flex-1">
&nbsp;
@ -59,24 +64,29 @@ export const Filter: FunctionalComponent<FilterProps> = ({pageSizeFilter, workfl
</div>;
}
const BulkActions: FunctionalComponent = () => {
const BulkActions: FunctionalComponent<BulkActionsProps> = ({ onBulkDelete, onBulkCancel }) => {
const bulkActions = [{
text: 'Cancel',
name: 'Cancel',
}, {
text: 'Delete',
name: 'Delete',
}, {
text: 'Cancel',
name: 'Cancel',
}];
const onBulkActionSelected = (e: CustomEvent<DropdownButtonItem>) => {
const action = e.detail;
switch (action.name){
case 'Delete' :
switch (action.name) {
case 'Delete':
onBulkDelete();
break;
case 'Cancel':
onBulkCancel();
break;
default:
action.handler();
}
}
};
return <elsa-dropdown-button
text="Bulk Actions" items={bulkActions} icon={<BulkActionsIcon/>}

View file

@ -5,7 +5,6 @@ import {ElsaClientProvider} from "../../../services";
@Service()
export class WorkflowInstancesApi {
private provider: ElsaClientProvider;
constructor(provider: ElsaClientProvider) {
@ -49,9 +48,19 @@ export class WorkflowInstancesApi {
return response.data;
}
async deleteMany(request: BulkDeleteWorkflowInstancesRequest): Promise<PagedList<WorkflowInstanceSummary>> {
async deleteMany(request: BulkDeleteWorkflowInstancesRequest): Promise<number> {
const httpClient = await this.getHttpClient();
const response = await httpClient.delete<PagedList<WorkflowInstanceSummary>>(`workflow-instances/bulk`);
const response = await httpClient.post<number>(`bulk-actions/delete/workflow-instances/by-id`, {
Ids: request.workflowInstanceIds,
});
return response.data;
}
async cancelMany(request: BulkCancelWorkflowInstancesRequest): Promise<number> {
const httpClient = await this.getHttpClient();
const response = await httpClient.post<number>(`bulk-actions/cancel/workflow-instances/by-id`, {
Ids: request.workflowInstanceIds,
});
return response.data;
}
@ -97,8 +106,20 @@ export interface BulkDeleteWorkflowInstancesRequest {
workflowInstanceIds: Array<string>;
}
export interface BulkCancelWorkflowInstancesRequest {
workflowInstanceIds: Array<string>;
}
export interface GetWorkflowJournalRequest {
workflowInstanceId: string;
page?: number;
pageSize?: number;
}
export interface DeleteManyWorkflowInstancesResponse {
}
export interface DeleteManyWorkflowInstancesResponse {
}

View file

@ -31,25 +31,26 @@ internal class BulkRetract : ElsaEndpoint<Request, Response>
foreach (var definitionId in request.DefinitionIds)
{
var definition = (await _store.FindManyAsync(new WorkflowDefinitionFilter
var definitions = (await _store.FindManyAsync(new WorkflowDefinitionFilter
{
DefinitionId = definitionId,
VersionOptions = VersionOptions.Latest
}, cancellationToken: cancellationToken)).FirstOrDefault();
VersionOptions = VersionOptions.LatestOrPublished
}, cancellationToken: cancellationToken)).ToList();
if (definition == null)
if (!definitions.Any())
{
notFound.Add(definitionId);
continue;
}
if (!definition.IsPublished)
var published = definitions.FirstOrDefault(d => d.IsPublished);
if (published is null)
{
notPublished.Add(definitionId);
continue;
}
await _workflowDefinitionPublisher.RetractAsync(definition, cancellationToken);
await _workflowDefinitionPublisher.RetractAsync(published, cancellationToken);
retracted.Add(definitionId);
}