added simple notifications (#3184)
Co-authored-by: Ivan Hrynevytskyi <ivan.hrynevytskyi@IHRYNEVYTSKYIL.local>
This commit is contained in:
parent
92bc89b10c
commit
c67cb6ebdc
1414
src/designer/elsa-workflows-designer/package-lock.json
generated
1414
src/designer/elsa-workflows-designer/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -26,18 +26,19 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@antv/x6": "^1.32.2",
|
||||
"@ctrl/tinycolor": "^3.4.1",
|
||||
"@stencil/core": "^2.13.0",
|
||||
"@stencil/state-tunnel": "^1.0.1",
|
||||
"@stencil/store": "^1.5.0",
|
||||
"@ctrl/tinycolor": "^3.4.1",
|
||||
"axios": "^0.27.2",
|
||||
"axios-middleware": "^0.3.1",
|
||||
"el-transition": "^0.0.7",
|
||||
"lodash": "^4.17.21",
|
||||
"moment": "^2.29.3",
|
||||
"notyf": "^3.10.0",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"typedi": "^0.10.0",
|
||||
"lodash": "^4.17.21",
|
||||
"uuid": "^8.3.2",
|
||||
"el-transition": "^0.0.7",
|
||||
"moment": "^2.29.3"
|
||||
"uuid": "^8.3.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"monaco-editor": ""
|
||||
|
|
|
|||
|
|
@ -166,6 +166,8 @@ export namespace Components {
|
|||
interface ElsaMultiTextInput {
|
||||
"inputContext": ActivityInputContext;
|
||||
}
|
||||
interface ElsaNotificationsManager {
|
||||
}
|
||||
interface ElsaPager {
|
||||
"page": number;
|
||||
"pageSize": number;
|
||||
|
|
@ -440,6 +442,12 @@ declare global {
|
|||
prototype: HTMLElsaMultiTextInputElement;
|
||||
new (): HTMLElsaMultiTextInputElement;
|
||||
};
|
||||
interface HTMLElsaNotificationsManagerElement extends Components.ElsaNotificationsManager, HTMLStencilElement {
|
||||
}
|
||||
var HTMLElsaNotificationsManagerElement: {
|
||||
prototype: HTMLElsaNotificationsManagerElement;
|
||||
new (): HTMLElsaNotificationsManagerElement;
|
||||
};
|
||||
interface HTMLElsaPagerElement extends Components.ElsaPager, HTMLStencilElement {
|
||||
}
|
||||
var HTMLElsaPagerElement: {
|
||||
|
|
@ -617,6 +625,7 @@ declare global {
|
|||
"elsa-monaco-editor": HTMLElsaMonacoEditorElement;
|
||||
"elsa-multi-line-input": HTMLElsaMultiLineInputElement;
|
||||
"elsa-multi-text-input": HTMLElsaMultiTextInputElement;
|
||||
"elsa-notifications-manager": HTMLElsaNotificationsManagerElement;
|
||||
"elsa-pager": HTMLElsaPagerElement;
|
||||
"elsa-panel": HTMLElsaPanelElement;
|
||||
"elsa-radio-list-input": HTMLElsaRadioListInputElement;
|
||||
|
|
@ -782,6 +791,8 @@ declare namespace LocalJSX {
|
|||
interface ElsaMultiTextInput {
|
||||
"inputContext"?: ActivityInputContext;
|
||||
}
|
||||
interface ElsaNotificationsManager {
|
||||
}
|
||||
interface ElsaPager {
|
||||
"onPaginated"?: (event: CustomEvent<PagerData>) => void;
|
||||
"page"?: number;
|
||||
|
|
@ -911,6 +922,7 @@ declare namespace LocalJSX {
|
|||
"elsa-monaco-editor": ElsaMonacoEditor;
|
||||
"elsa-multi-line-input": ElsaMultiLineInput;
|
||||
"elsa-multi-text-input": ElsaMultiTextInput;
|
||||
"elsa-notifications-manager": ElsaNotificationsManager;
|
||||
"elsa-pager": ElsaPager;
|
||||
"elsa-panel": ElsaPanel;
|
||||
"elsa-radio-list-input": ElsaRadioListInput;
|
||||
|
|
@ -968,6 +980,7 @@ declare module "@stencil/core" {
|
|||
"elsa-monaco-editor": LocalJSX.ElsaMonacoEditor & JSXBase.HTMLAttributes<HTMLElsaMonacoEditorElement>;
|
||||
"elsa-multi-line-input": LocalJSX.ElsaMultiLineInput & JSXBase.HTMLAttributes<HTMLElsaMultiLineInputElement>;
|
||||
"elsa-multi-text-input": LocalJSX.ElsaMultiTextInput & JSXBase.HTMLAttributes<HTMLElsaMultiTextInputElement>;
|
||||
"elsa-notifications-manager": LocalJSX.ElsaNotificationsManager & JSXBase.HTMLAttributes<HTMLElsaNotificationsManagerElement>;
|
||||
"elsa-pager": LocalJSX.ElsaPager & JSXBase.HTMLAttributes<HTMLElsaPagerElement>;
|
||||
"elsa-panel": LocalJSX.ElsaPanel & JSXBase.HTMLAttributes<HTMLElsaPanelElement>;
|
||||
"elsa-radio-list-input": LocalJSX.ElsaRadioListInput & JSXBase.HTMLAttributes<HTMLElsaRadioListInputElement>;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import {Component, Element, h, Listen, Prop, Watch} from '@stencil/core';
|
||||
import 'reflect-metadata';
|
||||
import {Container} from 'typedi';
|
||||
import {ElsaApiClientProvider, ElsaClient, ServerSettings} from '../../../services';
|
||||
import {ElsaApiClientProvider, ElsaClient, EventBus, ServerSettings} from '../../../services';
|
||||
import {ActivityDescriptor, VersionOptions, WorkflowDefinition, WorkflowDefinitionSummary, WorkflowInstanceSummary} from '../../../models';
|
||||
import {PublishClickedArgs} from "../../toolbar/workflow-publish-button/workflow-publish-button";
|
||||
import {MonacoEditorSettings} from "../../../services/monaco-editor-settings";
|
||||
|
|
@ -11,17 +11,20 @@ import {WorkflowDefinitionManager} from "../../../services/workflow-definition-m
|
|||
import {WorkflowDefinitionUpdatedArgs} from "../../designer/workflow-definition-editor/models";
|
||||
import {Flowchart} from "../../activities/flowchart/models";
|
||||
import descriptorsStore from '../../../data/descriptors-store';
|
||||
import { NotificationEventTypes } from '../../../modules/notifications/event-types';
|
||||
|
||||
@Component({
|
||||
tag: 'elsa-studio'
|
||||
})
|
||||
export class Studio {
|
||||
private readonly eventBus: EventBus;
|
||||
private readonly workflowDefinitionManager: WorkflowDefinitionManager;
|
||||
private activityDescriptors: Array<ActivityDescriptor>;
|
||||
private elsaClient: ElsaClient;
|
||||
private workflowManagerElement?: HTMLElsaWorkflowManagerElement;
|
||||
|
||||
constructor() {
|
||||
this.eventBus = Container.get(EventBus);
|
||||
this.workflowDefinitionManager = Container.get(WorkflowDefinitionManager);
|
||||
}
|
||||
|
||||
|
|
@ -85,12 +88,13 @@ export class Studio {
|
|||
private async handlePublishClicked(e: CustomEvent<PublishClickedArgs>) {
|
||||
const workflowManagerElement = this.workflowManagerElement;
|
||||
|
||||
if (!workflowManagerElement)
|
||||
return;
|
||||
if (!workflowManagerElement) return;
|
||||
|
||||
e.detail.begin();
|
||||
const workflowDefinition = await workflowManagerElement.getWorkflowDefinition();
|
||||
this.eventBus.emit(NotificationEventTypes.Add, this, { id: workflowDefinition.definitionId, message: `Starting publishing ${workflowDefinition.name}` });
|
||||
await this.saveWorkflowDefinition(workflowDefinition, true);
|
||||
this.eventBus.emit(NotificationEventTypes.Update, this, { id: workflowDefinition.definitionId, message: `${workflowDefinition.name} publish finished` });
|
||||
e.detail.complete();
|
||||
}
|
||||
|
||||
|
|
@ -98,11 +102,12 @@ export class Studio {
|
|||
private async handleUnPublishClicked(e: CustomEvent) {
|
||||
const workflowManagerElement = this.workflowManagerElement;
|
||||
|
||||
if (!workflowManagerElement)
|
||||
return;
|
||||
if (!workflowManagerElement) return;
|
||||
|
||||
const workflow = await workflowManagerElement.getWorkflowDefinition();
|
||||
this.eventBus.emit(NotificationEventTypes.Add, this, { id: workflow.definitionId, message: `Starting unpublishing ${workflow.name}` });
|
||||
await this.retractWorkflowDefinition(workflow);
|
||||
this.eventBus.emit(NotificationEventTypes.Update, this, { id: workflow.definitionId, message: `${workflow.name} unpublish finished` });
|
||||
}
|
||||
|
||||
@Listen('newClicked')
|
||||
|
|
|
|||
|
|
@ -1,36 +1,57 @@
|
|||
import {Component, h} from '@stencil/core';
|
||||
import { Component, h } from '@stencil/core';
|
||||
import Container from 'typedi';
|
||||
import { NotificationEventTypes } from '../../../modules/notifications/event-types';
|
||||
import { EventBus } from '../../../services';
|
||||
|
||||
@Component({
|
||||
tag: 'elsa-workflow-toolbar'
|
||||
tag: 'elsa-workflow-toolbar',
|
||||
})
|
||||
export class WorkflowToolbar {
|
||||
private readonly eventBus: EventBus;
|
||||
|
||||
constructor() {
|
||||
this.eventBus = Container.get(EventBus);
|
||||
}
|
||||
|
||||
onNotificationClick = e => {
|
||||
e.stopPropagation();
|
||||
this.eventBus.emit(NotificationEventTypes.Toggle, this);
|
||||
};
|
||||
|
||||
render() {
|
||||
return <nav class="bg-gray-800">
|
||||
<div class="mx-auto px-2 sm:px-6 lg:px-6">
|
||||
<div class="relative flex items-center justify-end h-16">
|
||||
return (
|
||||
<nav class="bg-gray-800">
|
||||
<div class="mx-auto px-2 sm:px-6 lg:px-6">
|
||||
<div class="relative flex items-center justify-end h-16">
|
||||
<div class="absolute inset-y-0 right-0 flex items-center pr-2 sm:static sm:inset-auto sm:ml-6 sm:pr-0 z-20">
|
||||
{/* Notifications*/}
|
||||
<button
|
||||
onClick={e => this.onNotificationClick(e)}
|
||||
type="button"
|
||||
class="bg-gray-800 p-1 rounded-full text-gray-400 hover:text-white focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-800 focus:ring-white mr-4"
|
||||
>
|
||||
<span class="sr-only">View notifications</span>
|
||||
<svg class="h-6 w-6" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<div class="absolute inset-y-0 right-0 flex items-center pr-2 sm:static sm:inset-auto sm:ml-6 sm:pr-0 z-20">
|
||||
{/* Publish */}
|
||||
<div class="flex-shrink-0">
|
||||
<elsa-workflow-publish-button />
|
||||
</div>
|
||||
|
||||
{/* Notifications*/}
|
||||
<button type="button" class="bg-gray-800 p-1 rounded-full text-gray-400 hover:text-white focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-800 focus:ring-white mr-4">
|
||||
<span class="sr-only">View notifications</span>
|
||||
<svg class="h-6 w-6" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9"/>
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
{/* Publish */}
|
||||
<div class="flex-shrink-0">
|
||||
<elsa-workflow-publish-button/>
|
||||
{/* Menu */}
|
||||
<elsa-workflow-toolbar-menu />
|
||||
</div>
|
||||
|
||||
{/* Menu */}
|
||||
<elsa-workflow-toolbar-menu/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>;
|
||||
</nav>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
<div class="absolute inset-0" style="top: 64px;">
|
||||
<elsa-workflow-manager></elsa-workflow-manager>
|
||||
<elsa-labels-widget></elsa-labels-widget>
|
||||
<elsa-notifications-manager></elsa-notifications-manager>
|
||||
</div>
|
||||
<!-- <elsa-workflow-editor></elsa-workflow-editor>-->
|
||||
</elsa-studio>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
export const NotificationEventTypes = {
|
||||
Add: 'notification-added',
|
||||
Update: 'notification-updated',
|
||||
Toggle: 'notification-toggle',
|
||||
};
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
export interface Notification {
|
||||
message: string;
|
||||
id: string;
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
import { Component, h, State } from '@stencil/core';
|
||||
import { Container } from 'typedi';
|
||||
import notificationStore from './notification-store';
|
||||
import { EventBus } from '../../services';
|
||||
import { Notyf, NotyfNotification } from 'notyf';
|
||||
import { Notification } from './models';
|
||||
import { NotificationEventTypes } from './event-types';
|
||||
|
||||
@Component({
|
||||
tag: 'elsa-notifications-manager',
|
||||
shadow: false,
|
||||
styleUrl: 'notification.scss',
|
||||
})
|
||||
export class LabelsManager {
|
||||
private readonly eventBus: EventBus;
|
||||
private readonly notyf: Notyf;
|
||||
|
||||
@State() private isOpened = false;
|
||||
private notyfs: Map<string, NotyfNotification> = new Map();
|
||||
|
||||
constructor() {
|
||||
this.notyf = new Notyf({ types: [{ type: 'regular', className: 'notif p-4 rounded bg-white shadow-lg' }] });
|
||||
|
||||
this.eventBus = Container.get(EventBus);
|
||||
this.eventBus.on(NotificationEventTypes.Add, this.handleAddNotification);
|
||||
this.eventBus.on(NotificationEventTypes.Update, this.handleUpdateNotification);
|
||||
this.eventBus.on(NotificationEventTypes.Toggle, this.handleToggle);
|
||||
}
|
||||
|
||||
handleAddNotification = (e: Notification) => {
|
||||
if (!this.isOpened) {
|
||||
this.notyfs.set(e.id, this.notyf.success({ message: e.message, type: 'regular', duration: 2000, position: { x: 'right', y: 'top' } }));
|
||||
}
|
||||
notificationStore.notifications = [e, ...notificationStore.notifications];
|
||||
};
|
||||
|
||||
handleUpdateNotification = (e: Notification) => {
|
||||
if (!this.isOpened) {
|
||||
this.notyf.dismiss(this.notyfs.get(e.id));
|
||||
this.notyfs.set(e.id, this.notyf.success({ message: e.message, type: 'regular', duration: 2000, position: { x: 'right', y: 'top' } }));
|
||||
}
|
||||
notificationStore.notifications = [e, ...notificationStore.notifications];
|
||||
};
|
||||
|
||||
handleToggle = () => {
|
||||
if (!this.isOpened) {
|
||||
this.notyf.dismissAll();
|
||||
this.notyfs.clear();
|
||||
}
|
||||
this.isOpened = !this.isOpened;
|
||||
};
|
||||
|
||||
render() {
|
||||
const { notifications } = notificationStore;
|
||||
|
||||
return (
|
||||
<div class={`notifications-container absolute bg-white z-10 right-0 w-80 ${this.isOpened ? 'block' : 'hidden'} `}>
|
||||
{notifications.length === 0 && <div class="m-4 p-4 rounded border border-black bg-white shadow-lg">There is no notifications yet</div>}
|
||||
{notifications.map(notif => (
|
||||
<div class="m-4 p-4 rounded border border-black bg-white shadow-lg">{notif.message}</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
import { createStore } from '@stencil/store';
|
||||
|
||||
const { state, onChange } = createStore({
|
||||
notifications: [],
|
||||
});
|
||||
|
||||
export default state;
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
@import url('../../../node_modules/notyf/notyf.min.css');
|
||||
|
||||
.notif {
|
||||
.notyf__message {
|
||||
@apply text-black
|
||||
}
|
||||
}
|
||||
|
||||
.notifications-container {
|
||||
height: calc(100vh - 64px);
|
||||
}
|
||||
Loading…
Reference in a new issue