Implement record selection
This commit is contained in:
parent
ffafe42948
commit
f20fdbf437
|
|
@ -5,7 +5,7 @@
|
|||
* It contains typing information for all components that exist in this project.
|
||||
*/
|
||||
import { HTMLStencilElement, JSXBase } from "@stencil/core/internal";
|
||||
import { ActivityDefinitionProperty, ActivityDescriptor, ActivityDesignDisplayContext, ActivityModel, ActivityPropertyDescriptor, VersionOptions, WorkflowBlueprint, WorkflowDefinition, WorkflowModel } from "./models";
|
||||
import { ActivityDefinitionProperty, ActivityDescriptor, ActivityDesignDisplayContext, ActivityModel, ActivityPropertyDescriptor, VersionOptions, WorkflowBlueprint, WorkflowDefinition, WorkflowExecutionLogRecord, WorkflowModel } from "./models";
|
||||
import { MatchResults, RouterHistory } from "@stencil/router";
|
||||
import { MenuItem } from "./components/controls/elsa-context-menu/models";
|
||||
import { DropdownButtonItem, DropdownButtonOrigin } from "./components/controls/elsa-dropdown-button/models";
|
||||
|
|
@ -36,10 +36,12 @@ export namespace Components {
|
|||
interface ElsaDesignerTree {
|
||||
"destroyJsPlumb": () => Promise<void>;
|
||||
"model": WorkflowModel;
|
||||
"selectedActivityId"?: string;
|
||||
}
|
||||
interface ElsaDesignerTreeActivity {
|
||||
"displayContext": ActivityDesignDisplayContext;
|
||||
"icon": string;
|
||||
"selected": boolean;
|
||||
}
|
||||
interface ElsaDropdownButton {
|
||||
"icon"?: any;
|
||||
|
|
@ -482,12 +484,14 @@ declare namespace LocalJSX {
|
|||
interface ElsaDesignerTree {
|
||||
"model"?: WorkflowModel;
|
||||
"onWorkflow-changed"?: (event: CustomEvent<WorkflowModel>) => void;
|
||||
"selectedActivityId"?: string;
|
||||
}
|
||||
interface ElsaDesignerTreeActivity {
|
||||
"displayContext"?: ActivityDesignDisplayContext;
|
||||
"icon"?: string;
|
||||
"onEdit-activity"?: (event: CustomEvent<ActivityModel>) => void;
|
||||
"onRemove-activity"?: (event: CustomEvent<ActivityModel>) => void;
|
||||
"selected"?: boolean;
|
||||
}
|
||||
interface ElsaDropdownButton {
|
||||
"icon"?: any;
|
||||
|
|
@ -619,6 +623,7 @@ declare namespace LocalJSX {
|
|||
}
|
||||
interface ElsaWorkflowInstanceJournal {
|
||||
"activityDescriptors"?: Array<ActivityDescriptor>;
|
||||
"onRecordSelected"?: (event: CustomEvent<WorkflowExecutionLogRecord>) => void;
|
||||
"serverUrl"?: string;
|
||||
"workflowBlueprint"?: WorkflowBlueprint;
|
||||
"workflowInstanceId"?: string;
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ export class ElsaDesignerTreeActivity {
|
|||
|
||||
@Prop() displayContext: ActivityDesignDisplayContext
|
||||
@Prop() icon: string
|
||||
@Prop() selected: boolean;
|
||||
@Event({eventName: 'remove-activity', bubbles: true}) removeActivityEmitter: EventEmitter<ActivityModel>;
|
||||
@Event({eventName: 'edit-activity', bubbles: true}) editActivityEmitter: EventEmitter<ActivityModel>;
|
||||
@State() showMenu: boolean
|
||||
|
|
@ -45,11 +46,12 @@ export class ElsaDesignerTreeActivity {
|
|||
const activity = displayContext.activityModel;
|
||||
const activityId = activity.activityId;
|
||||
const displayName = activity.displayName && activity.displayName.length > 0 ? activity.displayName : activity.name && activity.name.length > 0 ? activity.name : activity.type
|
||||
const activityClass = this.selected ? 'border-blue-600' : 'border-white hover:border-blue-600';
|
||||
|
||||
return (
|
||||
<Host id={`activity-${activityId}`}
|
||||
onDblClick={e => this.onEditActivityClick(e)}
|
||||
class="activity border-2 border-solid border-white rounded bg-white text-left text-black text-lg hover:border-blue-600 select-none max-w-md shadow-sm relative">
|
||||
class={`${activityClass} activity border-2 border-solid rounded bg-white text-left text-black text-lg select-none max-w-md shadow-sm relative`}>
|
||||
<div class="p-5">
|
||||
<div class="flex justify-between space-x-8">
|
||||
<div class="flex-shrink-0">
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import state from "../../../../utils/store";
|
|||
export class ElsaWorkflowDesigner {
|
||||
|
||||
@Prop() model: WorkflowModel = { activities: [], connections: [], persistenceBehavior: WorkflowPersistenceBehavior.WorkflowBurst };
|
||||
@Prop() selectedActivityId?: string;
|
||||
@Event({eventName: 'workflow-changed', bubbles: true, composed: true, cancelable: true}) workflowChanged: EventEmitter<WorkflowModel>
|
||||
@State() workflowModel: WorkflowModel
|
||||
el: HTMLElement
|
||||
|
|
@ -536,7 +537,10 @@ export class ElsaWorkflowDesigner {
|
|||
}
|
||||
|
||||
renderActivity(displayContext: ActivityDesignDisplayContext) {
|
||||
return <elsa-designer-tree-activity displayContext={displayContext} draggable={true}
|
||||
const selected = this.selectedActivityId == displayContext.activityModel.activityId;
|
||||
return <elsa-designer-tree-activity displayContext={displayContext}
|
||||
draggable={true}
|
||||
selected={selected}
|
||||
onDragStart={e => this.onDragStartActivity(e, displayContext)}
|
||||
/>;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import {Component, h, Host, Method, Prop, State, Watch} from '@stencil/core';
|
||||
import {Component, EventEmitter, h, Host, Method, Prop, State, Watch, Event} from '@stencil/core';
|
||||
import moment from 'moment';
|
||||
import {enter, leave, toggle} from 'el-transition'
|
||||
import {registerClickOutside} from "stencil-click-outside";
|
||||
|
|
@ -19,8 +19,10 @@ export class ElsaWorkflowInstanceJournal {
|
|||
@Prop() serverUrl: string;
|
||||
@Prop() activityDescriptors: Array<ActivityDescriptor> = [];
|
||||
@Prop() workflowBlueprint: WorkflowBlueprint;
|
||||
@Event() recordSelected: EventEmitter<WorkflowExecutionLogRecord>;
|
||||
@State() isVisible: boolean = true;
|
||||
@State() records: PagedList<WorkflowExecutionLogRecord> = {items: [], totalCount: 0};
|
||||
@State() selectedRecordId?: string;
|
||||
|
||||
el: HTMLElement;
|
||||
|
||||
|
|
@ -54,6 +56,18 @@ export class ElsaWorkflowInstanceJournal {
|
|||
await this.workflowInstanceIdChangedHandler(this.workflowInstanceId);
|
||||
}
|
||||
|
||||
getEventColor(eventName: string) {
|
||||
const map = {
|
||||
'Executing': 'blue',
|
||||
'Executed': 'green',
|
||||
'Faulted': 'rose',
|
||||
'Warning': 'yellow',
|
||||
'Information': 'blue',
|
||||
};
|
||||
|
||||
return map[eventName] || 'gray';
|
||||
}
|
||||
|
||||
onCloseClick() {
|
||||
this.hide();
|
||||
}
|
||||
|
|
@ -62,12 +76,18 @@ export class ElsaWorkflowInstanceJournal {
|
|||
this.show();
|
||||
}
|
||||
|
||||
onRecordClick(record: WorkflowExecutionLogRecord) {
|
||||
this.selectedRecordId = record.id;
|
||||
this.recordSelected.emit(record);
|
||||
}
|
||||
|
||||
render() {
|
||||
const records = this.records;
|
||||
const items = records.items;
|
||||
const activityDescriptors = this.activityDescriptors;
|
||||
const workflowBlueprint = this.workflowBlueprint;
|
||||
const activityBlueprints: Array<ActivityBlueprint> = workflowBlueprint.activities || [];
|
||||
const selectedRecordId = this.selectedRecordId;
|
||||
|
||||
const renderRecord = (record: WorkflowExecutionLogRecord, index: number) => {
|
||||
const isLastItem = index == items.length - 1;
|
||||
|
|
@ -80,6 +100,9 @@ export class ElsaWorkflowInstanceJournal {
|
|||
const activityDescriptor = activityDescriptors.find(x => x.type === activityType);
|
||||
const activityBlueprint = activityBlueprints.find(x => x.id === record.activityId) || {name: null, displayName: null};
|
||||
const activityName = activityBlueprint.displayName || activityBlueprint.name || activityDescriptor.displayName || activityDescriptor.type;
|
||||
const eventName = record.eventName;
|
||||
const eventColor = this.getEventColor(eventName);
|
||||
const recordClass = record.id === selectedRecordId ? 'border-blue-600' : 'hover:bg-gray-100 border-transparent';
|
||||
|
||||
const deltaTimeText = !!deltaTime ? deltaTime.asHours() > 1
|
||||
? `${deltaTime.asHours()} h`
|
||||
|
|
@ -92,7 +115,7 @@ export class ElsaWorkflowInstanceJournal {
|
|||
|
||||
return (
|
||||
<li>
|
||||
<div class="hover:bg-gray-100 cursor-pointer p-4 rounded">
|
||||
<div onClick={() => this.onRecordClick(record)} class={`${recordClass} border-2 cursor-pointer p-4 rounded`}>
|
||||
<div class="relative pb-10">
|
||||
{isLastItem ? undefined : <div class="flex absolute top-8 left-4 -ml-px h-full w-0.5 bg-gray-200">
|
||||
<div class="flex flex-1 items-center relative -left-5">
|
||||
|
|
@ -112,9 +135,12 @@ export class ElsaWorkflowInstanceJournal {
|
|||
</h3>
|
||||
</div>
|
||||
<div>
|
||||
<span class="relative inline-flex items-center rounded-full border border-gray-300 px-3 py-0.5 text-sm">
|
||||
<span class="font-medium text-gray-900">{record.eventName}</span>
|
||||
</span>
|
||||
<span class="relative inline-flex items-center rounded-full border border-gray-300 px-3 py-0.5 text-sm">
|
||||
<span class="absolute flex-shrink-0 flex items-center justify-center">
|
||||
<span class={`h-1.5 w-1.5 rounded-full bg-${eventColor}-500`} aria-hidden="true"/>
|
||||
</span>
|
||||
<span class="ml-3.5 font-medium text-gray-900">{eventName}</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="text-right text-sm whitespace-nowrap text-gray-500">
|
||||
<span>{currentTimestamp.format('DD-MM-YYYY HH:mm:ss')}</span>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import {
|
|||
ActivityModel, Connection,
|
||||
ConnectionModel,
|
||||
EventTypes, SyntaxNames,
|
||||
WorkflowBlueprint,
|
||||
WorkflowBlueprint, WorkflowExecutionLogRecord,
|
||||
WorkflowInstance,
|
||||
WorkflowModel,
|
||||
WorkflowPersistenceBehavior,
|
||||
|
|
@ -32,6 +32,7 @@ export class ElsaWorkflowInstanceViewerScreen {
|
|||
@State() workflowInstance: WorkflowInstance;
|
||||
@State() workflowBlueprint: WorkflowBlueprint;
|
||||
@State() workflowModel: WorkflowModel;
|
||||
@State() selectedActivityId?: string;
|
||||
el: HTMLElement;
|
||||
designer: HTMLElsaDesignerTreeElement;
|
||||
|
||||
|
|
@ -157,12 +158,20 @@ export class ElsaWorkflowInstanceViewerScreen {
|
|||
eventBus.emit(EventTypes.ShowWorkflowSettings);
|
||||
}
|
||||
|
||||
onRecordSelected(e: CustomEvent<WorkflowExecutionLogRecord>) {
|
||||
this.selectedActivityId = e.detail.activityId;
|
||||
}
|
||||
|
||||
render() {
|
||||
const descriptors: Array<ActivityDescriptor> = state.activityDescriptors;
|
||||
return (
|
||||
<Host class="flex flex-col w-full relative" ref={el => this.el = el}>
|
||||
{this.renderCanvas()}
|
||||
<elsa-workflow-instance-journal workflowInstanceId={this.workflowInstanceId} serverUrl={this.serverUrl} activityDescriptors={descriptors} workflowBlueprint={this.workflowBlueprint}/>
|
||||
<elsa-workflow-instance-journal workflowInstanceId={this.workflowInstanceId}
|
||||
serverUrl={this.serverUrl}
|
||||
activityDescriptors={descriptors}
|
||||
workflowBlueprint={this.workflowBlueprint}
|
||||
onRecordSelected={e => this.onRecordSelected(e)}/>
|
||||
</Host>
|
||||
);
|
||||
}
|
||||
|
|
@ -170,7 +179,7 @@ export class ElsaWorkflowInstanceViewerScreen {
|
|||
renderCanvas() {
|
||||
return (
|
||||
<div class="flex-1 flex">
|
||||
<elsa-designer-tree model={this.workflowModel} class="flex-1" ref={el => this.designer = el}/>
|
||||
<elsa-designer-tree model={this.workflowModel} class="flex-1" ref={el => this.designer = el} selectedActivityId={this.selectedActivityId}/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue