Added error handling messages. Restyled notifications. Notifications are now hidden when opening the menu. (#3878)

This commit is contained in:
simona-taran 2023-04-11 11:07:37 +03:00 committed by GitHub
parent 8ca73e10b3
commit c2582cb356
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 114 additions and 49 deletions

View file

@ -8,7 +8,6 @@ import { HTMLStencilElement, JSXBase } from "@stencil/core/internal";
import { InputDefinition, OutputDefinition, WorkflowDefinition, WorkflowDefinitionSummary } from "./modules/workflow-definitions/models/entities";
import { Activity, ActivityDeletedArgs, ActivitySelectedArgs, ChildActivitySelectedArgs, ContainerSelectedArgs, EditChildActivityArgs, GraphUpdatedArgs, IntellisenseContext, SelectListItem, TabChangedArgs, TabDefinition, Variable, WorkflowExecutionLogRecord, WorkflowInstance, WorkflowInstanceSummary, WorkflowUpdatedArgs } from "./models";
import { ActivityUpdatedArgs, DeleteActivityRequestedArgs, Widget, WorkflowDefinitionPropsUpdatedArgs, WorkflowDefinitionUpdatedArgs } from "./modules/workflow-definitions/models/ui";
import { NotificationType } from "./modules/notifications/models";
import { Button } from "./components/shared/button-group/models";
import { ActivityInputContext } from "./services/activity-input-driver";
import { ContextMenuAnchorPoint, ContextMenuItem } from "./components/shared/context-menu/models";
@ -23,6 +22,7 @@ import { SignedInArgs } from "./modules/login/models";
import { ModalActionClickArgs, ModalActionDefinition, ModalDialogInstance } from "./components/shared/modal-dialog/models";
import { ModalType } from "./components/shared/modal-dialog/modal-type";
import { MonacoValueChangedArgs } from "./components/shared/monaco-editor/monaco-editor";
import { NotificationType } from "./modules/notifications/models";
import { PagerData } from "./components/shared/pager/pager";
import { PanelPosition, PanelStateChangedArgs } from "./components/panel/models";
import { RenderActivityPropsContext } from "./modules/workflow-definitions/components/models";
@ -54,10 +54,6 @@ export namespace Components {
"variables": Array<Variable>;
"workflowDefinitionId": string;
}
interface ElsaAwhileNotifications {
"notification": NotificationType;
"showDuration": number;
}
interface ElsaButtonGroup {
"buttons": Array<Button>;
}
@ -241,6 +237,10 @@ export namespace Components {
}
interface ElsaToastManager {
}
interface ElsaToastNotification {
"notification": NotificationType;
"showDuration": number;
}
interface ElsaTooltip {
"tooltipContent": any;
"tooltipPosition"?: string;
@ -487,12 +487,6 @@ declare global {
prototype: HTMLElsaActivityPropertiesEditorElement;
new (): HTMLElsaActivityPropertiesEditorElement;
};
interface HTMLElsaAwhileNotificationsElement extends Components.ElsaAwhileNotifications, HTMLStencilElement {
}
var HTMLElsaAwhileNotificationsElement: {
prototype: HTMLElsaAwhileNotificationsElement;
new (): HTMLElsaAwhileNotificationsElement;
};
interface HTMLElsaButtonGroupElement extends Components.ElsaButtonGroup, HTMLStencilElement {
}
var HTMLElsaButtonGroupElement: {
@ -715,6 +709,12 @@ declare global {
prototype: HTMLElsaToastManagerElement;
new (): HTMLElsaToastManagerElement;
};
interface HTMLElsaToastNotificationElement extends Components.ElsaToastNotification, HTMLStencilElement {
}
var HTMLElsaToastNotificationElement: {
prototype: HTMLElsaToastNotificationElement;
new (): HTMLElsaToastNotificationElement;
};
interface HTMLElsaTooltipElement extends Components.ElsaTooltip, HTMLStencilElement {
}
var HTMLElsaTooltipElement: {
@ -870,7 +870,6 @@ declare global {
"elsa-activity-output-editor-dialog-content": HTMLElsaActivityOutputEditorDialogContentElement;
"elsa-activity-properties": HTMLElsaActivityPropertiesElement;
"elsa-activity-properties-editor": HTMLElsaActivityPropertiesEditorElement;
"elsa-awhile-notifications": HTMLElsaAwhileNotificationsElement;
"elsa-button-group": HTMLElsaButtonGroupElement;
"elsa-check-list-input": HTMLElsaCheckListInputElement;
"elsa-checkbox-input": HTMLElsaCheckboxInputElement;
@ -908,6 +907,7 @@ declare global {
"elsa-studio": HTMLElsaStudioElement;
"elsa-switch-editor": HTMLElsaSwitchEditorElement;
"elsa-toast-manager": HTMLElsaToastManagerElement;
"elsa-toast-notification": HTMLElsaToastNotificationElement;
"elsa-tooltip": HTMLElsaTooltipElement;
"elsa-type-picker-input": HTMLElsaTypePickerInputElement;
"elsa-variable-editor-dialog-content": HTMLElsaVariableEditorDialogContentElement;
@ -957,10 +957,6 @@ declare namespace LocalJSX {
"variables"?: Array<Variable>;
"workflowDefinitionId"?: string;
}
interface ElsaAwhileNotifications {
"notification"?: NotificationType;
"showDuration"?: number;
}
interface ElsaButtonGroup {
"buttons"?: Array<Button>;
}
@ -1148,6 +1144,10 @@ declare namespace LocalJSX {
}
interface ElsaToastManager {
}
interface ElsaToastNotification {
"notification"?: NotificationType;
"showDuration"?: number;
}
interface ElsaTooltip {
"tooltipContent"?: any;
"tooltipPosition"?: string;
@ -1263,7 +1263,6 @@ declare namespace LocalJSX {
"elsa-activity-output-editor-dialog-content": ElsaActivityOutputEditorDialogContent;
"elsa-activity-properties": ElsaActivityProperties;
"elsa-activity-properties-editor": ElsaActivityPropertiesEditor;
"elsa-awhile-notifications": ElsaAwhileNotifications;
"elsa-button-group": ElsaButtonGroup;
"elsa-check-list-input": ElsaCheckListInput;
"elsa-checkbox-input": ElsaCheckboxInput;
@ -1301,6 +1300,7 @@ declare namespace LocalJSX {
"elsa-studio": ElsaStudio;
"elsa-switch-editor": ElsaSwitchEditor;
"elsa-toast-manager": ElsaToastManager;
"elsa-toast-notification": ElsaToastNotification;
"elsa-tooltip": ElsaTooltip;
"elsa-type-picker-input": ElsaTypePickerInput;
"elsa-variable-editor-dialog-content": ElsaVariableEditorDialogContent;
@ -1336,7 +1336,6 @@ declare module "@stencil/core" {
"elsa-activity-output-editor-dialog-content": LocalJSX.ElsaActivityOutputEditorDialogContent & JSXBase.HTMLAttributes<HTMLElsaActivityOutputEditorDialogContentElement>;
"elsa-activity-properties": LocalJSX.ElsaActivityProperties & JSXBase.HTMLAttributes<HTMLElsaActivityPropertiesElement>;
"elsa-activity-properties-editor": LocalJSX.ElsaActivityPropertiesEditor & JSXBase.HTMLAttributes<HTMLElsaActivityPropertiesEditorElement>;
"elsa-awhile-notifications": LocalJSX.ElsaAwhileNotifications & JSXBase.HTMLAttributes<HTMLElsaAwhileNotificationsElement>;
"elsa-button-group": LocalJSX.ElsaButtonGroup & JSXBase.HTMLAttributes<HTMLElsaButtonGroupElement>;
"elsa-check-list-input": LocalJSX.ElsaCheckListInput & JSXBase.HTMLAttributes<HTMLElsaCheckListInputElement>;
"elsa-checkbox-input": LocalJSX.ElsaCheckboxInput & JSXBase.HTMLAttributes<HTMLElsaCheckboxInputElement>;
@ -1374,6 +1373,7 @@ declare module "@stencil/core" {
"elsa-studio": LocalJSX.ElsaStudio & JSXBase.HTMLAttributes<HTMLElsaStudioElement>;
"elsa-switch-editor": LocalJSX.ElsaSwitchEditor & JSXBase.HTMLAttributes<HTMLElsaSwitchEditorElement>;
"elsa-toast-manager": LocalJSX.ElsaToastManager & JSXBase.HTMLAttributes<HTMLElsaToastManagerElement>;
"elsa-toast-notification": LocalJSX.ElsaToastNotification & JSXBase.HTMLAttributes<HTMLElsaToastNotificationElement>;
"elsa-tooltip": LocalJSX.ElsaTooltip & JSXBase.HTMLAttributes<HTMLElsaTooltipElement>;
"elsa-type-picker-input": LocalJSX.ElsaTypePickerInput & JSXBase.HTMLAttributes<HTMLElsaTypePickerInputElement>;
"elsa-variable-editor-dialog-content": LocalJSX.ElsaVariableEditorDialogContent & JSXBase.HTMLAttributes<HTMLElsaVariableEditorDialogContentElement>;

View file

@ -2,8 +2,9 @@ import {Component, Event, EventEmitter, Host, h, Listen, Prop, State} from '@ste
import {leave, toggle} from 'el-transition';
import {EventBus} from "../../../services";
import {Container} from "typedi";
import {ToolbarDisplayingArgs, ToolbarEventTypes, ToolbarMenu, ToolbarMenuItem} from "./models";
import {ToolbarMenuItem} from "./models";
import toolbarButtonMenuItemStore from "../../../data/toolbar-button-menu-item-store";
import NotificationService from "../../../modules/notifications/notification-service";
@Component({
tag: 'elsa-workflow-toolbar-menu',
@ -13,6 +14,7 @@ export class WorkflowToolbarMenu {
private readonly eventBus: EventBus;
private menu: HTMLElement;
private element: HTMLElement;
private isMenuOpen = false;
constructor() {
this.eventBus = Container.get(EventBus);
@ -20,10 +22,15 @@ export class WorkflowToolbarMenu {
private closeMenu = () => {
leave(this.menu);
this.isMenuOpen = false;
};
private toggleMenu = () => {
toggle(this.menu);
this.isMenuOpen = !this.isMenuOpen;
if (this.isMenuOpen) {
NotificationService.hideAllNotifications();
}
};
render() {

View file

@ -4,13 +4,13 @@ import {NotificationEventTypes} from '../../../modules/notifications/event-types
import {EventBus} from '../../../services';
import toolbarComponentStore from "../../../data/toolbar-component-store";
import notificationService from '../../../modules/notifications/notification-service';
import notificationStore from "../../../modules/notifications/notification-store";
@Component({
tag: 'elsa-workflow-toolbar',
assetsDirs: ['assets']
})
export class WorkflowToolbar {
@State() public modalState: boolean = false;
private readonly eventBus: EventBus;
static NotificationService = notificationService;
@ -23,11 +23,12 @@ export class WorkflowToolbar {
e.stopPropagation();
await this.eventBus.emit(NotificationEventTypes.Toggle, this);
WorkflowToolbar.NotificationService.toggleNotification();
this.modalState = !this.modalState;
};
render() {
const logoPath = getAssetPath('./assets/logo.png');
const infoPanelBoolean = notificationStore.infoPanelBoolean;
return (
<div>
<nav class="bg-gray-800">
@ -81,7 +82,7 @@ export class WorkflowToolbar {
</div>
</nav>
<elsa-notifications-manager modalState={this.modalState}></elsa-notifications-manager>
<elsa-notifications-manager modalState={infoPanelBoolean}></elsa-notifications-manager>
<elsa-toast-manager></elsa-toast-manager>
</div>
);

View file

@ -3,7 +3,7 @@ import {Moment} from "moment";
export interface NotificationType {
id?: number | any;
title: string;
text: string;
text: string | JSX.Element;
type?: NotificationDisplayType;
timestamp?: Moment;
showToast?: boolean;

View file

@ -24,9 +24,6 @@ export class NotificationManager {
static NotificationServiceLocal = NotificationService;
constructor() {
}
deleteNotif = (id) => {
notificationStore.notifications = notificationStore.notifications.filter(item => item.id !== id)
}

View file

@ -37,4 +37,18 @@ export default class NotificationService {
notificationStore.notifications = notifications;
}
}
static hideAllNotifications = () => {
notificationStore.infoPanelBoolean = false;
notificationStore.notifications = notificationStore.notifications.map((notification) => {
if (notification.showToast !== false) {
return {
...notification,
showToast: false
}
}
return notification;
});
}
}

View file

@ -66,7 +66,7 @@ export class NotificationTemplate {
<div class="ml-3 w-0 flex-1 pt-0.5 z-30">
<p class="text-sm font-medium text-gray-900">{notification.title}</p>
<p class="mt-1 text-sm text-gray-500">{notification.text}</p>
<p class="mt-1 text-sm text-gray-500">{this.time}</p>
<p class="mt-1 text-sm text-gray-700 text-right">{this.time}</p>
</div>
<div class="ml-4 flex flex-shrink-0 z-30">
<slot name="close-button"/>

View file

@ -14,7 +14,7 @@ export class ToastManager {
if (notification) {
return (
<elsa-awhile-notifications notification={notification}></elsa-awhile-notifications>
<elsa-toast-notification notification={notification}></elsa-toast-notification>
);
} else {
return null;

View file

@ -4,11 +4,11 @@ import notificationStore from "./notification-store";
import NotificationService from "./notification-service";
@Component({
tag: 'elsa-awhile-notifications',
tag: 'elsa-toast-notification',
shadow: false,
styleUrl: '',
})
export class NotificationAwhile {
export class ToastNotification {
@Prop() public notification: NotificationType;
@Prop() public showDuration = 6000;
private timer;

View file

@ -67,7 +67,8 @@ export class WorkflowDefinitionsPlugin implements Plugin {
}
async initialize(): Promise<void> {
this.inputControlRegistry.add("workflow-definition-picker", c => <elsa-workflow-definition-picker-input inputContext={c}/>);
this.inputControlRegistry.add("workflow-definition-picker", c => <elsa-workflow-definition-picker-input
inputContext={c}/>);
}
newWorkflow = async () => {
@ -106,7 +107,7 @@ export class WorkflowDefinitionsPlugin implements Plugin {
private saveWorkflowDefinition = async (definition: WorkflowDefinition, publish: boolean): Promise<WorkflowDefinition> => {
if(!definition.isLatest) {
if (!definition.isLatest) {
console.debug('Workflow definition is not latest. Skipping save.');
return;
}
@ -129,8 +130,12 @@ export class WorkflowDefinitionsPlugin implements Plugin {
}
public showWorkflowDefinitionEditor = (workflowDefinition: WorkflowDefinition) => {
toolbarComponentStore.components = [() => <elsa-workflow-publish-button onPublishClicked={this.onPublishClicked} onExportClicked={this.onExportClicked} onImportClicked={this.onImportClicked}/>];
studioComponentStore.activeComponentFactory = () => <elsa-workflow-definition-editor workflowDefinition={workflowDefinition} onWorkflowUpdated={this.onWorkflowUpdated} ref={el => this.workflowDefinitionEditorElement = el}/>;
toolbarComponentStore.components = [() => <elsa-workflow-publish-button onPublishClicked={this.onPublishClicked}
onExportClicked={this.onExportClicked}
onImportClicked={this.onImportClicked}/>];
studioComponentStore.activeComponentFactory = () => <elsa-workflow-definition-editor
workflowDefinition={workflowDefinition} onWorkflowUpdated={this.onWorkflowUpdated}
ref={el => this.workflowDefinitionEditorElement = el}/>;
};
private import = async () => {
@ -166,7 +171,15 @@ export class WorkflowDefinitionsPlugin implements Plugin {
public onWorkflowUpdated = async (e: CustomEvent<WorkflowDefinitionUpdatedArgs>) => {
const updatedWorkflowDefinition = e.detail.workflowDefinition;
await this.saveWorkflowDefinition(updatedWorkflowDefinition, false);
await this.saveWorkflowDefinition(updatedWorkflowDefinition, false)
.catch(() => {
NotificationService.createNotification({
title: 'Error while saving',
id: uuid(),
text: <span>Workflow {e.detail.workflowDefinition.definitionId} could not be saved. </span>,
type: NotificationDisplayType.Error
});
});
}
private onBrowseWorkflowDefinitions = async () => {
@ -175,7 +188,8 @@ export class WorkflowDefinitionsPlugin implements Plugin {
const actions = [closeAction, newAction];
this.workflowDefinitionBrowserInstance = this.modalDialogService.show(() =>
<elsa-workflow-definition-browser onWorkflowDefinitionSelected={this.onWorkflowDefinitionSelected} onNewWorkflowDefinitionSelected={this.onNewWorkflowDefinitionSelected}/>,
<elsa-workflow-definition-browser onWorkflowDefinitionSelected={this.onWorkflowDefinitionSelected}
onNewWorkflowDefinitionSelected={this.onNewWorkflowDefinitionSelected}/>,
{actions})
}
@ -186,14 +200,14 @@ export class WorkflowDefinitionsPlugin implements Plugin {
this.modalDialogService.hide(this.workflowDefinitionBrowserInstance);
}
public publishCurrentWorkflow = async (args: PublishClickedArgs)=>{
return this.onPublishClicked(new CustomEvent('PublishClickedArgs',{detail:args}));
public publishCurrentWorkflow = async (args: PublishClickedArgs) => {
return this.onPublishClicked(new CustomEvent('PublishClickedArgs', {detail: args}));
}
private onPublishClicked = async (e: CustomEvent<PublishClickedArgs>) => {
const definition = await this.workflowDefinitionEditorElement.getWorkflowDefinition();
if(!definition.isLatest) {
if (!definition.isLatest) {
console.debug('Workflow definition is not latest. Skipping publish.');
return;
}
@ -207,13 +221,21 @@ export class WorkflowDefinitionsPlugin implements Plugin {
type: NotificationDisplayType.InProgress
});
await this.saveWorkflowDefinition(definition, true);
await this.saveWorkflowDefinition(definition, true)
.then(async () => {
NotificationService.updateNotification(notification, {title: 'Workflow published', text: 'Published!'})
e.detail.complete();
NotificationService.updateNotification(notification, {title: 'Workflow published', text: 'Published!'})
e.detail.complete();
// Reload activity descriptors.
await this.activityDescriptorManager.refresh();
// Reload activity descriptors.
await this.activityDescriptorManager.refresh();
}).catch(() => {
NotificationService.updateNotification(notification, {
title: 'Error while publishing',
text: <span>Workflow {definition.definitionId} could not be published.</span>,
type: NotificationDisplayType.Error
});
e.detail.complete();
});
}
private onExportClicked = async (e: CustomEvent) => {

View file

@ -10,6 +10,9 @@ import {WorkflowInstancesApi} from "./services/workflow-instances-api";
import {WorkflowDefinition} from "../workflow-definitions/models/entities";
import {h} from "@stencil/core";
import studioComponentStore from "../../data/studio-component-store";
import NotificationService from "../notifications/notification-service";
import {uuid} from "@antv/x6/es/util/string/uuid";
import {NotificationDisplayType} from "../notifications/models";
@Service()
export class WorkflowInstancesPlugin implements Plugin {
@ -60,9 +63,30 @@ export class WorkflowInstancesPlugin implements Plugin {
const definitionId = e.detail.definitionId;
const instanceId = e.detail.id;
const version = e.detail.version;
const workflowDefinition = await this.workflowDefinitionsApi.get({definitionId, versionOptions: {version}, includeCompositeRoot: true});
const workflowInstance = await this.workflowInstancesApi.get({id: instanceId});
this.showWorkflowInstanceViewer(workflowDefinition, workflowInstance);
this.modalDialogService.hide(this.workflowInstanceBrowserInstance);
await this.workflowDefinitionsApi.get({definitionId, versionOptions: {version}, includeCompositeRoot: true})
.then(async (workflowDefinition) => {
await this.workflowInstancesApi.get({id: instanceId}).then((workflowInstance) => {
this.showWorkflowInstanceViewer(workflowDefinition, workflowInstance);
this.modalDialogService.hide(this.workflowInstanceBrowserInstance);
}).catch(() => {
NotificationService.createNotification({
title: 'Error',
id: uuid(),
text: <div>Could not load workflow instance {instanceId} information</div>,
type: NotificationDisplayType.Error
});
this.modalDialogService.hide(this.workflowInstanceBrowserInstance);
});
}).catch(() => {
NotificationService.createNotification({
title: 'Error',
id: uuid(),
text: <div>Could not load workflow {definitionId} information</div>,
type: NotificationDisplayType.Error
});
this.modalDialogService.hide(this.workflowInstanceBrowserInstance);
});
}
}