Incremental work on journal UI

This commit is contained in:
Sipke Schoorstra 2022-06-03 22:26:47 +02:00
parent d0685f8794
commit a81c5c63da
5 changed files with 86 additions and 114 deletions

View file

@ -231,6 +231,7 @@ export namespace Components {
"workflowInstance": WorkflowInstance;
}
interface ElsaWorkflowJournal {
"workflowInstanceId": any;
}
interface ElsaWorkflowManager {
"activityDescriptors": Array<ActivityDescriptor>;
@ -757,6 +758,7 @@ declare namespace LocalJSX {
"workflowInstance"?: WorkflowInstance;
}
interface ElsaWorkflowJournal {
"workflowInstanceId"?: any;
}
interface ElsaWorkflowManager {
"activityDescriptors"?: Array<ActivityDescriptor>;

View file

@ -122,6 +122,9 @@ export class WorkflowViewer {
}
public render() {
const workflowInstance = this.workflowInstance;
const workflowInstanceId = workflowInstance?.id;
const tunnelState: WorkflowDesignerState = {
workflow: this.workflowDefinition,
activityDescriptors: this.activityDescriptors,
@ -134,7 +137,7 @@ export class WorkflowViewer {
class="elsa-activity-picker-container"
position={PanelPosition.Left}
onExpandedStateChanged={e => this.onActivityPickerPanelStateChanged(e.detail)}>
<elsa-workflow-journal />
<elsa-workflow-journal workflowInstanceId={workflowInstanceId}/>
</elsa-panel>
<elsa-canvas
class="absolute" ref={el => this.canvas = el}

View file

@ -1,12 +1,37 @@
import {Component, h} from "@stencil/core";
import {isNullOrWhitespace} from "../../../utils";
import {Component, h, Prop, State, Watch} from "@stencil/core";
import {WorkflowExecutionLogRecord} from "../../../models";
import {Container} from "typedi";
import {ElsaApiClientProvider} from "../../../services";
const PAGE_SIZE: number = 20;
@Component({
tag: 'elsa-workflow-journal',
shadow: false
})
export class WorkflowJournal {
private readonly elsaApiClientProvider: ElsaApiClientProvider;
constructor() {
this.elsaApiClientProvider = Container.get(ElsaApiClientProvider);
}
@Prop() workflowInstanceId;
@State() workflowExecutionLogRecords: Array<WorkflowExecutionLogRecord> = [];
@Watch('workflowInstanceId')
async onWorkflowInstanceIdChanged(value: string) {
await this.loadJournalPage(0);
}
async componentWillLoad() {
await this.loadJournalPage(0);
}
public render() {
const records = this.workflowExecutionLogRecords;
return (
<div>
@ -23,129 +48,44 @@ export class WorkflowJournal {
<div class="flow-root p-4 overflow-hidden">
<ul role="list" class="-mb-8">
<li>
<div class="relative pb-8">
<span class="absolute top-4 left-4 -ml-px h-full w-0.5 bg-gray-200" aria-hidden="true"/>
<div class="relative flex space-x-3">
<div>
{records.map(record => (
<li>
<div class="relative pb-8">
<span class="absolute top-4 left-4 -ml-px h-full w-0.5 bg-gray-200" aria-hidden="true"/>
<div class="relative flex space-x-3">
<div>
<span class="h-8 w-8 rounded-full bg-gray-400 flex items-center justify-center ring-8 ring-white">
<svg class="h-5 w-5 text-white" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
<path fill-rule="evenodd" d="M10 9a3 3 0 100-6 3 3 0 000 6zm-7 9a7 7 0 1114 0H3z" clip-rule="evenodd"/>
</svg>
</span>
</div>
<div class="min-w-0 flex-1 pt-1.5 flex justify-between space-x-4">
<div>
<p class="text-sm text-gray-500">Applied to <a href="#" class="font-medium text-gray-900">Front End Developer</a></p>
</div>
<div class="text-right text-sm whitespace-nowrap text-gray-500">
<time dateTime="2020-09-20">Sep 20</time>
<div class="min-w-0 flex-1 pt-1.5 flex justify-between space-x-4">
<div>
<p class="text-sm text-gray-500">Applied to <a href="#" class="font-medium text-gray-900">Front End Developer</a></p>
</div>
<div class="text-right text-sm whitespace-nowrap text-gray-500">
<time dateTime="2020-09-20">Sep 20</time>
</div>
</div>
</div>
</div>
</div>
</li>
</li>
))}
<li>
<div class="relative pb-8">
<span class="absolute top-4 left-4 -ml-px h-full w-0.5 bg-gray-200" aria-hidden="true"></span>
<div class="relative flex space-x-3">
<div>
<span class="h-8 w-8 rounded-full bg-blue-500 flex items-center justify-center ring-8 ring-white">
<svg class="h-5 w-5 text-white" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
<path
d="M2 10.5a1.5 1.5 0 113 0v6a1.5 1.5 0 01-3 0v-6zM6 10.333v5.43a2 2 0 001.106 1.79l.05.025A4 4 0 008.943 18h5.416a2 2 0 001.962-1.608l1.2-6A2 2 0 0015.56 8H12V4a2 2 0 00-2-2 1 1 0 00-1 1v.667a4 4 0 01-.8 2.4L6.8 7.933a4 4 0 00-.8 2.4z"/>
</svg>
</span>
</div>
<div class="min-w-0 flex-1 pt-1.5 flex justify-between space-x-4">
<div>
<p class="text-sm text-gray-500">Advanced to phone screening by <a href="#" class="font-medium text-gray-900">Bethany Blake</a></p>
</div>
<div class="text-right text-sm whitespace-nowrap text-gray-500">
<time dateTime="2020-09-22">Sep 22</time>
</div>
</div>
</div>
</div>
</li>
<li>
<div class="relative pb-8">
<span class="absolute top-4 left-4 -ml-px h-full w-0.5 bg-gray-200" aria-hidden="true"></span>
<div class="relative flex space-x-3">
<div>
<span class="h-8 w-8 rounded-full bg-green-500 flex items-center justify-center ring-8 ring-white">
<svg class="h-5 w-5 text-white" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/>
</svg>
</span>
</div>
<div class="min-w-0 flex-1 pt-1.5 flex justify-between space-x-4">
<div>
<p class="text-sm text-gray-500">Completed phone screening with <a href="#" class="font-medium text-gray-900">Martha Gardner</a></p>
</div>
<div class="text-right text-sm whitespace-nowrap text-gray-500">
<time dateTime="2020-09-28">Sep 28</time>
</div>
</div>
</div>
</div>
</li>
<li>
<div class="relative pb-8">
<span class="absolute top-4 left-4 -ml-px h-full w-0.5 bg-gray-200" aria-hidden="true"></span>
<div class="relative flex space-x-3">
<div>
<span class="h-8 w-8 rounded-full bg-blue-500 flex items-center justify-center ring-8 ring-white">
<svg class="h-5 w-5 text-white" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
<path
d="M2 10.5a1.5 1.5 0 113 0v6a1.5 1.5 0 01-3 0v-6zM6 10.333v5.43a2 2 0 001.106 1.79l.05.025A4 4 0 008.943 18h5.416a2 2 0 001.962-1.608l1.2-6A2 2 0 0015.56 8H12V4a2 2 0 00-2-2 1 1 0 00-1 1v.667a4 4 0 01-.8 2.4L6.8 7.933a4 4 0 00-.8 2.4z"/>
</svg>
</span>
</div>
<div class="min-w-0 flex-1 pt-1.5 flex justify-between space-x-4">
<div>
<p class="text-sm text-gray-500">Advanced to interview by <a href="#" class="font-medium text-gray-900">Bethany Blake</a></p>
</div>
<div class="text-right text-sm whitespace-nowrap text-gray-500">
<time dateTime="2020-09-30">Sep 30</time>
</div>
</div>
</div>
</div>
</li>
<li>
<div class="relative pb-8">
<div class="relative flex space-x-3">
<div>
<span class="h-8 w-8 rounded-full bg-green-500 flex items-center justify-center ring-8 ring-white">
<svg class="h-5 w-5 text-white" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/>
</svg>
</span>
</div>
<div class="min-w-0 flex-1 pt-1.5 flex justify-between space-x-4">
<div>
<p class="text-sm text-gray-500">Completed interview with <a href="#" class="font-medium text-gray-900">Katherine Snyder</a></p>
</div>
<div class="text-right text-sm whitespace-nowrap text-gray-500">
<time dateTime="2020-10-04">Oct 4</time>
</div>
</div>
</div>
</div>
</li>
</ul>
</div>
</div>
);
}
private loadJournalPage = async (page: number): Promise<void> => {
if (!this.workflowInstanceId)
return;
const client = await this.elsaApiClientProvider.getElsaClient();
const pageOfRecords = await client.workflowInstances.getJournal({page, pageSize: PAGE_SIZE, workflowInstanceId: this.workflowInstanceId})
this.workflowExecutionLogRecords = [...this.workflowExecutionLogRecords, ...pageOfRecords.items];
}
}

View file

@ -1,7 +1,7 @@
import {Type} from "./shared";
import {Expression} from "./expressions";
export type Lookup<T> = { [key: string]: T};
export type Lookup<T> = { [key: string]: T };
export interface Activity {
id: string;
@ -79,6 +79,14 @@ export interface RegisterLocation {
value: any;
}
export interface WorkflowExecutionLogRecord {
id: string;
activityId: string;
activityType: string;
timestamp: Date;
eventName: string;
}
export enum SyntaxNames {
Literal = 'Literal',
JavaScript = 'JavaScript',

View file

@ -1,4 +1,4 @@
import {OrderBy, OrderDirection, PagedList, VersionOptions, WorkflowInstance, WorkflowInstanceSummary, WorkflowStatus, WorkflowSubStatus} from "../../models";
import {OrderBy, OrderDirection, PagedList, VersionOptions, WorkflowExecutionLogRecord, WorkflowInstance, WorkflowInstanceSummary, WorkflowStatus, WorkflowSubStatus} from "../../models";
import {AxiosInstance} from "axios";
import {getVersionOptionsString, serializeQueryString} from "../../utils";
@ -11,6 +11,8 @@ export interface WorkflowInstancesApi {
delete(request: DeleteWorkflowInstanceRequest): Promise<WorkflowInstanceSummary>
deleteMany(request: BulkDeleteWorkflowInstancesRequest): Promise<PagedList<WorkflowInstanceSummary>>
getJournal(request: GetWorkflowJournalRequest): Promise<PagedList<WorkflowExecutionLogRecord>>;
}
export interface ListWorkflowInstancesRequest {
@ -39,6 +41,12 @@ export interface BulkDeleteWorkflowInstancesRequest {
workflowInstanceIds: Array<string>;
}
export interface GetWorkflowJournalRequest {
workflowInstanceId: string;
page?: number;
pageSize?: number;
}
export class WorkflowInstancesApiImpl implements WorkflowInstancesApi {
private httpClient: AxiosInstance;
@ -84,4 +92,15 @@ export class WorkflowInstancesApiImpl implements WorkflowInstancesApi {
const response = await this.httpClient.delete<PagedList<WorkflowInstanceSummary>>(`workflow-instances/bulk`);
return response.data;
}
async getJournal(request: GetWorkflowJournalRequest): Promise<PagedList<WorkflowExecutionLogRecord>> {
let queryString = {
page: request.page,
pageSize: request.pageSize
};
const queryStringText = serializeQueryString(queryString);
const response = await this.httpClient.get<PagedList<WorkflowExecutionLogRecord>>(`workflow-instances/${request.workflowInstanceId}/journal${queryStringText}`);
return response.data;
}
}