* ignoring start button click in Test mode * #1651: added word-break to endpoint URL * #1651: refresh test panel on workflow execute, if activity is already selected * removed clipboard permission checks that failed to build Seems like an old ongoing issue with TypeScript: https://github.com/microsoft/TypeScript/issues/33923 * #1651: fixed flyout panel position * #1651: flyout panel button position fix * #1651: fixed javascript evaluation exception being swallowed * #1651: added copy button to http entry endpoint url * #1651: test panel refactoring, use schema button for SendHttpRequest * #1651: add node is not clickable in test mode * fixed "can't access property "contains", this.contextMenuWidget is undefined" * added couple safeguard checks to context menu * reversed incorrect update * #1651: added z-index to toaster to move it to front * removed unnecessary empty line
This commit is contained in:
parent
e116ca8624
commit
bccb32b003
|
|
@ -328,6 +328,7 @@ namespace Elsa.Services.Workflows
|
|||
_logger.LogWarning(e, "Failed to run activity {ActivityId} of workflow {WorkflowInstanceId}", activity.Id, activityExecutionContext.WorkflowInstance.Id);
|
||||
activityExecutionContext.Fault(e);
|
||||
await _mediator.Publish(new ActivityFaulted(e, activityExecutionContext, activity), cancellationToken);
|
||||
await _mediator.Publish(new ActivityExecutionResultFailed(e, activityExecutionContext), cancellationToken);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -31,7 +31,8 @@ export class ElsaContextMenu {
|
|||
}
|
||||
|
||||
closeContextMenu() {
|
||||
leave(this.contextMenu);
|
||||
if (!!this.contextMenu)
|
||||
leave(this.contextMenu);
|
||||
}
|
||||
|
||||
toggleMenu() {
|
||||
|
|
|
|||
|
|
@ -187,14 +187,11 @@ export class ElsaWorkflowDesigner {
|
|||
}
|
||||
|
||||
async copyActivitiesToClipboard() {
|
||||
this.checkClipboardPermissions();
|
||||
await navigator.clipboard.writeText(JSON.stringify(this.selectedActivities));
|
||||
await eventBus.emit(EventTypes.ClipboardCopied, this);
|
||||
}
|
||||
|
||||
async pasteActivitiesFromClipboard() {
|
||||
this.checkClipboardPermissions();
|
||||
|
||||
let copiedActivities: Array<ActivityModel> = [];
|
||||
|
||||
await navigator.clipboard.readText().then(data => {
|
||||
|
|
@ -233,13 +230,6 @@ export class ElsaWorkflowDesigner {
|
|||
this.parentActivityOutcome = null;
|
||||
}
|
||||
|
||||
checkClipboardPermissions() {
|
||||
navigator.permissions.query({name: "clipboard-read"}).then((result) => {
|
||||
if (result.state == 'denied')
|
||||
eventBus.emit(EventTypes.ClipboardPermissionDenied, this);
|
||||
});
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
eventBus.on(EventTypes.ActivityPicked, this.onActivityPicked);
|
||||
eventBus.on(EventTypes.UpdateActivity, this.onUpdateActivity);
|
||||
|
|
@ -715,8 +705,8 @@ export class ElsaWorkflowDesigner {
|
|||
d3.select(node.elem).select('svg').classed('elsa-text-green-400', true).classed('elsa-text-gray-400', false).classed('hover:elsa-text-blue-500', false);
|
||||
return;
|
||||
}
|
||||
|
||||
await this.showActivityPicker();
|
||||
|
||||
if (this.mode !== WorkflowDesignerMode.Test) await this.showActivityPicker();
|
||||
})
|
||||
.on("mouseover", e => {
|
||||
if (e.shiftKey)
|
||||
|
|
@ -737,6 +727,8 @@ export class ElsaWorkflowDesigner {
|
|||
root.selectAll('.node.start').each((n: any) => {
|
||||
const node = this.graph.node(n) as any;
|
||||
d3.select(node.elem).on('click', async e => {
|
||||
if (this.mode == WorkflowDesignerMode.Test) return;
|
||||
|
||||
await this.showActivityPicker();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ export class ElsaMultiExpressionEditor {
|
|||
onWindowClicked(event: Event){
|
||||
const target = event.target as HTMLElement;
|
||||
|
||||
if (!this.contextMenuWidget.contains(target))
|
||||
if (!this.contextMenuWidget || !this.contextMenuWidget.contains(target))
|
||||
this.closeContextMenu();
|
||||
}
|
||||
|
||||
|
|
@ -53,7 +53,8 @@ export class ElsaMultiExpressionEditor {
|
|||
}
|
||||
|
||||
closeContextMenu() {
|
||||
leave(this.contextMenu);
|
||||
if (!!this.contextMenu)
|
||||
leave(this.contextMenu);
|
||||
}
|
||||
|
||||
selectDefaultEditor(e: Event) {
|
||||
|
|
|
|||
|
|
@ -593,9 +593,9 @@ export class ElsaWorkflowDefinitionEditorScreen {
|
|||
onActivityDeselected={e => this.onActivityDeselected(e)}
|
||||
class="elsa-flex-1"
|
||||
ref={el => this.designer = el}/>
|
||||
{this.renderPanel()}
|
||||
{this.renderWorkflowSettingsButton()}
|
||||
{this.renderWorkflowHelpButton()}
|
||||
{this.renderPanel()}
|
||||
{this.renderActivityContextMenu()}
|
||||
{this.renderConnectionContextMenu()}
|
||||
<elsa-workflow-settings-modal workflowDefinition={this.workflowDefinition}/>
|
||||
|
|
|
|||
|
|
@ -60,6 +60,10 @@ export class ElsaWorkflowTestPanel {
|
|||
if (message.workflowStatus == 'Executed') {
|
||||
this.workflowStarted = false;
|
||||
}
|
||||
|
||||
if (!this.message && message.activityId == this.workflowTestActivityId){
|
||||
this.message = message;
|
||||
}
|
||||
});
|
||||
|
||||
this.hubConnection.start()
|
||||
|
|
@ -110,6 +114,28 @@ export class ElsaWorkflowTestPanel {
|
|||
const workflowStatus = this.workflowTestActivityMessages.last().workflowStatus;
|
||||
|
||||
const t = (x, params?) => this.i18next.t(x, params);
|
||||
|
||||
const renderEndpointUrl = () => {
|
||||
if (!message.activityData || !message.activityData["Path"]) return undefined;
|
||||
|
||||
const endpointUrl = this.serverUrl + '/workflows' + message.activityData["Path"].value + '?correlation=' + message.correlationId;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div class="elsa-py-3 elsa-flex elsa-justify-between elsa-text-sm elsa-font-medium">
|
||||
<dt class="elsa-text-gray-500">
|
||||
<span class="elsa-mr-1">{t('EntryEndpoint')}</span>
|
||||
<elsa-copy-button value={endpointUrl} />
|
||||
</dt>
|
||||
</div>
|
||||
<div class="elsa-py-3 elsa-flex elsa-justify-between elsa-text-sm elsa-font-medium">
|
||||
<dt class="elsa-text-gray-900">
|
||||
<span class="elsa-break-all font-mono" onClick={e => clip(e.currentTarget)}>{endpointUrl}</span>
|
||||
</dt>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<dl class="elsa-border-b elsa-border-gray-200 elsa-divide-y elsa-divide-gray-200">
|
||||
|
|
@ -117,20 +143,7 @@ export class ElsaWorkflowTestPanel {
|
|||
<dt class="elsa-text-gray-500">{t('Status')}</dt>
|
||||
<dd class="elsa-text-gray-900">{workflowStatus}</dd>
|
||||
</div>
|
||||
{!!message.activityData["Path"] ?
|
||||
<div>
|
||||
<div class="elsa-py-3 elsa-flex elsa-justify-between elsa-text-sm elsa-font-medium">
|
||||
<dt class="elsa-text-gray-500">{t('EntryEndpoint')}</dt>
|
||||
</div>
|
||||
<div class="elsa-py-3 elsa-flex elsa-justify-between elsa-text-sm elsa-font-medium">
|
||||
<dt class="elsa-text-gray-900">
|
||||
<pre onClick={e => clip(e.currentTarget)}>{this.serverUrl + '/workflows' + message.activityData["Path"].value + '?correlation=' + message.correlationId}</pre>
|
||||
</dt>
|
||||
</div>
|
||||
</div>
|
||||
:
|
||||
undefined
|
||||
}
|
||||
{renderEndpointUrl()}
|
||||
</dl>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,17 +24,7 @@ export class ElsaCopyButton {
|
|||
onCopyClick = async (e) => {
|
||||
e.stopPropagation();
|
||||
|
||||
this.checkClipboardPermissions();
|
||||
|
||||
await navigator.clipboard.writeText(this.value);
|
||||
await eventBus.emit(EventTypes.ClipboardCopied, this, undefined, 'Data copied to clipboard.');
|
||||
}
|
||||
|
||||
checkClipboardPermissions = () => {
|
||||
navigator.permissions.query({name: 'clipboard-read'}).then((result) => {
|
||||
if (result.state == 'denied')
|
||||
eventBus.emit(EventTypes.ClipboardPermissionDenied, this);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ export class ElsaFlyoutPanel {
|
|||
<div class="elsa-absolute elsa-inset-0 elsa-overflow-hidden">
|
||||
<div class="elsa-absolute elsa-inset-0" aria-hidden="true"/>
|
||||
<div
|
||||
class="elsa-fixed elsa-inset-y-0 elsa-top-18 elsa-right-2 elsa-top-2 elsa-bottom-2 max-elsa-w-full elsa-flex">
|
||||
class="elsa-fixed elsa-top-20 elsa-inset-y-0 elsa-right-2 elsa-bottom-2 max-elsa-w-full elsa-flex">
|
||||
<div
|
||||
ref={el => this.el = el}
|
||||
data-transition-enter="elsa-transform elsa-transition elsa-ease-in-out elsa-duration-300 sm:elsa-duration-700"
|
||||
|
|
@ -63,7 +63,7 @@ export class ElsaFlyoutPanel {
|
|||
class="elsa-w-screen elsa-max-w-lg elsa-h-full ">
|
||||
<button type="button"
|
||||
onClick={this.toggle}
|
||||
class="workflow-settings-button elsa-absolute elsa-top-4 elsa-left-2 elsa-inline-flex elsa-items-center elsa-p-2 elsa-rounded-full elsa-border elsa-border-transparent elsa-bg-white shadow elsa-text-gray-400 hover:elsa-text-blue-500 focus:elsa-text-blue-500 hover:elsa-ring-2 hover:elsa-ring-offset-2 hover:elsa-ring-blue-500 focus:elsa-outline-none focus:elsa-ring-2 focus:elsa-ring-offset-2 focus:elsa-ring-blue-500 elsa-z-10">
|
||||
class="workflow-settings-button elsa-absolute elsa-left-2 elsa-inline-flex elsa-items-center elsa-p-2 elsa-rounded-full elsa-border elsa-border-transparent elsa-bg-white shadow elsa-text-gray-400 hover:elsa-text-blue-500 focus:elsa-text-blue-500 hover:elsa-ring-2 hover:elsa-ring-offset-2 hover:elsa-ring-blue-500 focus:elsa-outline-none focus:elsa-ring-2 focus:elsa-ring-offset-2 focus:elsa-ring-blue-500 elsa-z-10">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="elsa-h-8 elsa-w-8" fill="none" viewBox="0 0 24 24"
|
||||
stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ export class ElsaToastNotification {
|
|||
renderToast() {
|
||||
return (
|
||||
<Host class={{'hidden': !this.isVisible, 'elsa-block': true}}>
|
||||
<div class="elsa-fixed elsa-inset-0 elsa-flex elsa-items-end elsa-justify-center elsa-px-4 elsa-py-6 elsa-pointer-events-none sm:elsa-p-6 sm:elsa-items-start sm:elsa-justify-end">
|
||||
<div class="elsa-fixed elsa-inset-0 elsa-z-20 elsa-flex elsa-items-end elsa-justify-center elsa-px-4 elsa-py-6 elsa-pointer-events-none sm:elsa-p-6 sm:elsa-items-start sm:elsa-justify-end">
|
||||
<div ref={el => this.toast = el}
|
||||
data-transition-enter="elsa-transform elsa-ease-out elsa-duration-300 elsa-transition"
|
||||
data-transition-enter-start="elsa-translate-y-2 elsa-opacity-0 sm:elsa-translate-y-0 sm:elsa-translate-x-2"
|
||||
|
|
|
|||
|
|
@ -88,12 +88,16 @@ namespace Elsa.Server.Api.Handlers
|
|||
var signalRConnectionId = context.WorkflowExecutionContext.WorkflowInstance.GetMetadata("signalRConnectionId")?.ToString();
|
||||
if (string.IsNullOrWhiteSpace(signalRConnectionId)) return;
|
||||
|
||||
var innerMostException = notification.Exception;
|
||||
|
||||
while (innerMostException.InnerException != null) innerMostException = innerMostException.InnerException;
|
||||
|
||||
var message = new WorkflowTestMessage
|
||||
{
|
||||
WorkflowInstanceId = context.WorkflowInstance.Id,
|
||||
CorrelationId = context.CorrelationId,
|
||||
ActivityId = context.ActivityId,
|
||||
Error = notification.Exception.InnerException?.InnerException?.ToString()
|
||||
Error = innerMostException.ToString()
|
||||
};
|
||||
message.WorkflowStatus = message.Status = "Failed";
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue