added label filter to workflow definition modal (#3106)

Co-authored-by: Ivan Hrynevytskyi <ivan.hrynevytskyi@IHRYNEVYTSKYIL.local>

Closes #2985
This commit is contained in:
Ivan Hrynevytskyi (FE-underwriting) 2022-06-03 12:31:36 +03:00 committed by GitHub
parent 4d1349736c
commit c3f8997ea2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 42 additions and 5 deletions

View file

@ -119,6 +119,8 @@ export namespace Components {
"label": Label;
}
interface ElsaLabelPicker {
"buttonClass"?: string;
"containerClass"?: string;
"selectedLabels": Array<string>;
}
interface ElsaLabelsManager {
@ -658,6 +660,8 @@ declare namespace LocalJSX {
"onLabelUpdated"?: (event: CustomEvent<UpdateLabelEventArgs>) => void;
}
interface ElsaLabelPicker {
"buttonClass"?: string;
"containerClass"?: string;
"onSelectedLabelsChanged"?: (event: CustomEvent<Array<string>>) => void;
"selectedLabels"?: Array<string>;
}

View file

@ -1,5 +1,4 @@
import { FunctionalComponent, h } from '@stencil/core';
import { OrderBy } from '../../../models';
import { WorkflowDefinitionsOrderBy } from '../../../services/api-client/workflow-definitions-api';
import { BulkActionsIcon, OrderByIcon, PageSizeIcon } from '../../icons/tooling';
import { DropdownButtonItem, DropdownButtonOrigin } from '../../shared/dropdown-button/models';
@ -14,9 +13,17 @@ export interface OrderByFilterProps {
onChange: (orderBy: WorkflowDefinitionsOrderBy) => void;
}
export interface LabelFilterProps {
selectedLabels?: Array<string>;
onSelectedLabelsChanged: (e: CustomEvent<Array<string>>) => void;
buttonClass?: string;
containerClass?: string;
}
export interface FilterProps extends BulkActionsProps {
pageSizeFilter: PageSizeFilterProps;
orderByFilter: OrderByFilterProps;
labelFilter: LabelFilterProps;
}
export interface BulkActionsProps {
@ -25,13 +32,16 @@ export interface BulkActionsProps {
onBulkUnpublish: () => void;
}
export const Filter: FunctionalComponent<FilterProps> = ({ pageSizeFilter, orderByFilter, onBulkDelete, onBulkPublish, onBulkUnpublish }) => {
export const Filter: FunctionalComponent<FilterProps> = ({ pageSizeFilter, orderByFilter, onBulkDelete, onBulkPublish, onBulkUnpublish, labelFilter }) => {
return (
<div class="p-8 flex content-end justify-right bg-white space-x-4">
<div class="flex-shrink-0">
<BulkActions onBulkDelete={onBulkDelete} onBulkPublish={onBulkPublish} onBulkUnpublish={onBulkUnpublish} />
</div>
<div class="flex-1">&nbsp;</div>
<elsa-label-picker {...labelFilter} />
<PageSizeFilter {...pageSizeFilter} />
<OrderByFilter {...orderByFilter} />

View file

@ -29,6 +29,7 @@ export class WorkflowDefinitionBrowser {
@State() private currentPage: number = 0;
@State() private currentPageSize: number = WorkflowDefinitionBrowser.DEFAULT_PAGE_SIZE;
@State() private orderBy?: WorkflowDefinitionsOrderBy;
@State() private labels?: string[];
@State() private selectAllChecked: boolean;
@Method()
public async show() {
@ -107,6 +108,7 @@ export class WorkflowDefinitionBrowser {
pageSize: this.currentPageSize,
versionOptions: { isLatest: true },
orderBy: this.orderBy,
label: this.labels,
});
const unpublishedWorkflowDefinitionIds = latestWorkflowDefinitions.items.filter(x => !x.isPublished).map(x => x.definitionId);
this.publishedWorkflowDefinitions = await elsaClient.workflowDefinitions.list({
@ -133,6 +135,12 @@ export class WorkflowDefinitionBrowser {
selectedOrderBy: this.orderBy,
onChange: this.onOrderByChanged,
},
labelFilter: {
selectedLabels: this.labels,
onSelectedLabelsChanged: this.onLabelChange,
buttonClass: 'text-gray-500 hover:text-gray-300',
containerClass: 'mt-1.5',
},
onBulkDelete: this.onDeleteManyClick,
onBulkPublish: this.onPublishManyClick,
onBulkUnpublish: this.onUnpublishManyClick,
@ -254,6 +262,11 @@ export class WorkflowDefinitionBrowser {
await this.loadWorkflowDefinitions();
};
private onLabelChange = async (e: CustomEvent<Array<string>>) => {
this.labels = e.detail;
await this.loadWorkflowDefinitions();
};
private resetPagination = () => {
this.currentPage = 0;
this.selectedWorkflowDefinitionIds = [];

View file

@ -25,6 +25,8 @@ export class LabelPicker {
}
@Prop() public selectedLabels: Array<string> = [];
@Prop() public buttonClass?: string = 'text-blue-500 hover:text-blue-300';
@Prop() public containerClass?: string;
@Event() public selectedLabelsChanged: EventEmitter<Array<string>>;
@ -43,12 +45,12 @@ export class LabelPicker {
public render() {
const selectedLabels = this.getFilteredSelectedLabels();
return <div class="flex">
return <div class={`flex ${this.containerClass}`}>
<div class="flex flex-grow">
{selectedLabels.map(this.renderLabel)}
</div>
<div class="relative">
<button onClick={e => this.toggleFlyoutPanel()} class="text-blue-500 hover:text-blue-300">
<button onClick={e => this.toggleFlyoutPanel()} class={this.buttonClass}>
<ConfigIcon/>
</button>
{this.renderFlyout()}

View file

@ -88,6 +88,7 @@ export interface ListWorkflowDefinitionsRequest {
versionOptions?: VersionOptions;
materializerName?: string;
orderBy?: WorkflowDefinitionsOrderBy;
label?: Array<string>;
}
export interface DeleteManyWorkflowDefinitionResponse {
@ -155,6 +156,8 @@ export class WorkflowDefinitionsApiImpl implements WorkflowDefinitionsApi {
if (!!request.pageSize) queryString.orderBy = request.orderBy;
if (!!request.label) queryString.label = request.label;
const queryStringText = serializeQueryString(queryString);
const response = await this.httpClient.get<PagedList<WorkflowDefinitionSummary>>(`workflow-definitions${queryStringText}`);
return response.data;

View file

@ -70,6 +70,11 @@ export const isNullOrWhitespace = (input) => !input || !input.trim();
export const serializeQueryString = (queryString: object): string => {
const filteredItems = _(queryString).omitBy(_.isUndefined).omitBy(_.isNull).value();
const queryStringItems = _.map(filteredItems, (v, k) => `${k}=${v}`);
const queryStringItems = _.map(filteredItems, (v, k) => {
if (Array.isArray(v)) {
return v.map(item => `${k}=${item}`).join('&');
};
return `${k}=${v}`;
});
return queryStringItems.length > 0 ? `?${queryStringItems.join('&')}` : '';
};