refactor elsa notif service + design refactor

This commit is contained in:
Vadim Lev 2022-12-26 15:17:15 +02:00
parent 53ed26e24e
commit aad051abd6
8 changed files with 140 additions and 117 deletions

View file

@ -212,6 +212,7 @@ export namespace Components {
interface ElsaNewButton {
}
interface ElsaNotificationsManager {
"modalState": boolean;
}
interface ElsaPager {
"page": number;
@ -1029,6 +1030,7 @@ declare namespace LocalJSX {
"onNewClicked"?: (event: ElsaNewButtonCustomEvent<any>) => void;
}
interface ElsaNotificationsManager {
"modalState"?: boolean;
}
interface ElsaPager {
"onPaginated"?: (event: ElsaPagerCustomEvent<PagerData>) => void;

View file

@ -1,30 +1,37 @@
import {Component, h} from '@stencil/core';
import {Component, State, h} from '@stencil/core';
import Container from 'typedi';
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',
})
export class WorkflowToolbar {
@State() public modalState: boolean = false;
private readonly eventBus: EventBus;
static NotificationService = notificationService;
constructor() {
this.eventBus = Container.get(EventBus);
}
onNotificationClick = e => {
e.stopPropagation();
this.eventBus.emit(NotificationEventTypes.Toggle, this);
// this.eventBus.emit(NotificationEventTypes.Toggle, this);
WorkflowToolbar.NotificationService.toogleNotification();
this.modalState = !this.modalState;
};
render() {
const { notifications, infoPanelBoolean } = notificationStore;
return (
<div>
<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-40">
<div class="inset-y-0 right-0 flex items-center pr-2 sm:static sm:inset-auto sm:ml-6 sm:pr-0 z-40">
{/* Notifications*/}
<button
onClick={e => this.onNotificationClick(e)}
@ -54,6 +61,11 @@ export class WorkflowToolbar {
</div>
</div>
</nav>
<elsa-notifications-manager modalState={this.modalState}></elsa-notifications-manager>
{notifications && notifications.map(item => {
<elsa-awhile-notifications notification={item}></elsa-awhile-notifications>
})}
</div>
);
}
}

View file

@ -16,7 +16,6 @@
<div class="absolute inset-0" style="top: 64px;">
<elsa-studio server="https://localhost:5001/elsa/api" monaco-lib-path="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.31.1/min"></elsa-studio>
<elsa-custom-activities-manager></elsa-custom-activities-manager>
<elsa-notifications-manager></elsa-notifications-manager>
</div>
<script type="module">

View file

@ -1,4 +1,4 @@
import {Component, h, State, Prop } from "@stencil/core";
import {Component, h, State, Prop, Watch} from "@stencil/core";
import {NotificationType} from "./models";
@Component({
@ -8,52 +8,58 @@ import {NotificationType} from "./models";
})
export class NotificationAwhile {
@State() private isOpened = true;
@Prop() notification: NotificationType;
constructor() {
@Prop() public notification: NotificationType;
@Watch('notification')
onNotificationChange(){
console.log('sss')
}
componentDidRender() {
setTimeout(() => {
this.isOpened = false
}, 4000)
this.isOpened = false;
}, 6000)
}
render() {
const {title, text } = this.notification;
console.log(this.notification);
const {title, text} = this.notification;
return (
this.isOpened ? (
<div class='flex w-full flex-col items-center space-y-4 sm:items-end z-30'>
<div
class="pointer-events-auto w-full max-w-sm rounded-lg z-30 bg-white shadow-lg ring-1 ring-black ring-opacity-5">
<div class="p-4 z-30">
<div class="flex items-start z-30">
<div class="flex-shrink-0 z-30">
<svg class="h-6 w-6 text-green-400 z-30" xmlns="http://www.w3.org/2000/svg" fill="none"
viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round"
d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
</div>
<div class="ml-3 w-0 flex-1 pt-0.5 z-30">
<p class="text-sm font-medium text-gray-900">{title}</p>
<p class="mt-1 text-sm text-gray-500">{text}</p>
</div>
<div class="ml-4 flex flex-shrink-0 z-30">
<button
type="button"
// onclick={() => console.log(id)}
class="inline-flex rounded-md bg-white text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2">
<span class="sr-only">Close</span>
<svg class="h-5 w-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"
fill="currentColor" aria-hidden="true">
<path
d="M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z"/>
</svg>
</button>
<div
class="pointer-events-auto w-full max-w-sm rounded-lg z-50 bg-white shadow-lg ring-1 ring-black ring-opacity-5">
<div class="p-4 z-30">
<div class="flex items-start z-30">
<div class="flex-shrink-0 z-30">
<svg class="h-6 w-6 text-green-400 z-30" xmlns="http://www.w3.org/2000/svg" fill="none"
viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round"
d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
</div>
<div class="ml-3 w-0 flex-1 pt-0.5 z-30">
<p class="text-sm font-medium text-gray-900">{title}</p>
<p class="mt-1 text-sm text-gray-500">{text}</p>
</div>
<div class="ml-4 flex flex-shrink-0 z-30">
<button
type="button"
// onclick={() => console.log(id)}
class="inline-flex rounded-md bg-white text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2">
<span class="sr-only">Close</span>
<svg class="h-5 w-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"
fill="currentColor" aria-hidden="true">
<path
d="M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z"/>
</svg>
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div> )
: null
)

View file

@ -1,10 +1,13 @@
import { Component, h, State } from '@stencil/core';
import {Component, h, Prop, State, Watch} from '@stencil/core';
import { Container } from 'typedi';
import {enter, leave, toggle} from 'el-transition'
import notificationStore from './notification-store';
import { EventBus } from '../../services';
import { Notyf, NotyfNotification } from 'notyf';
import { NotificationType } from './models';
import { NotificationEventTypes } from './event-types';
import NotificationService from './notification-service';
import {Input} from "postcss";
@Component({
tag: 'elsa-notifications-manager',
@ -12,19 +15,21 @@ import { NotificationEventTypes } from './event-types';
styleUrl: 'notification.scss',
})
export class NotificationManager {
private readonly eventBus: EventBus;
private readonly notyf: Notyf;
@Prop() public modalState : boolean;
@State() private isOpened = false;
private notyfs: Map<string, NotyfNotification> = new Map();
@Watch('modalState')
onModalStateChange(value){
toggle(this.modal);
}
private readonly eventBus: EventBus;
modal: HTMLElement;
overlay: HTMLElement;
static NotificationServiceLocal = NotificationService;
constructor() {
this.notyf = new Notyf({ types: [{ type: 'regular', duration: 3000 }] });
// 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);
}
deleteNotif = (id) => {
@ -32,50 +37,37 @@ export class NotificationManager {
notificationStore.notifications = notificationStore.notifications.filter(item => item.id !== id)
}
//handleAddNotification = (e: NotificationType) => {
// if (!this.isOpened) {
// this.notyfs.set(e.id, this.notyf.success({ message: e.message, type: 'regular', duration: 400 }));
// }
//notificationStore.notifications = [e, ...notificationStore.notifications];
//};
//handleUpdateNotification = (e: NotificationType) => {
//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: 4000 }));
//}
//notificationStore.notifications = [e, ...notificationStore.notifications];
//};
handleToggle = () => {
if (!this.isOpened) {
this.notyf.dismissAll();
this.notyfs.clear();
}
this.isOpened = !this.isOpened;
NotificationManager.NotificationServiceLocal.toogleNotification();
toggle(this.modal);
};
private closeMenu() {
leave(this.modal);
}
private toggleMenu() {
toggle(this.modal);
}
render() {
const { notifications } = notificationStore;
console.log(notifications);
return (
return (
<div>
{notifications && notifications.map(item => (
<elsa-awhile-notifications notification={item}></elsa-awhile-notifications>
))}
<div data-transition-enter="transform transition ease-in-out duration-500 sm:duration-700"
<div
ref={el => this.modal = el}
data-transition-enter="transform transition ease-in-out duration-500 sm:duration-700"
data-transition-enter-start="translate-x-full"
data-transition-leave="transform transition ease-in-out duration-500 sm:duration-700"
data-transition-leave-start="translate-x-0"
data-transition-leave-end="translate-x-full"
class={`${this.isOpened ? 'block': 'hidden' } pt-65 z-30 fixed inset-y-0 right-0 flex max-w-full pl-10 sm:pl-16`}>
class='hidden z-50 pt-65 fixed inset-y-0 right-0 flex max-w-full pl-10 sm:pl-16'>
<div
class={`w-screen max-w-md `}>
<div class="w-screen max-w-md">
<div class="flex h-full flex-col overflow-y-scroll bg-white shadow-xl">
<div class="p-6">
<div class="p-6 border-b">
<div class="flex items-start justify-between">
<h2 class="text-lg font-medium text-gray-900" id="slide-over-title">Notifications</h2>
<div class="ml-3 flex h-7 items-center">
@ -91,53 +83,61 @@ export class NotificationManager {
</div>
</div>
</div>
{notifications.length === 0 && <div class="p-6 pointer-events-auto w-full max-w-sm overflow-hidden rounded-lg bg-white shadow-lg ring-1 ring-black ring-opacity-5">There is no notifications yet</div>}
<ul role="list" class="overflow-y-auto">
{notifications.length === 0 && <div class="p-6 pointer-events-auto w-full overflow-hidden border-b ring-1 ring-black ring-opacity-5">There is no notifications yet</div>}
<ul role="list" class=" pointer-events-auto overflow-y-auto flex-1 divide-y divide-gray-200 overflow-y-auto">
{notifications.map(notif => (
<li class="divide-y divide-gray-200" >
<div class=" space-x-2 group relative flex items-center py-4 px-5">
/* <li>
<div class="group relative flex items-center py-6 px-">
<div class="divide-y divide-gray-200 ml-4 truncate">
<p class="right-0 truncate text-sm text-gray-500">{notif.message}</p>
<p class="right-0 truncate text-sm text-gray-500">{notif.title}</p>
</div>
<div class="relative ml-2 inline-block flex-shrink-0 text-left">
{/* <button type="button"*/}
{/* class="group relative inline-flex h-8 w-8 items-center justify-center rounded-full bg-white focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"*/}
{/* id="options-menu-0-button" aria-expanded="false" aria-haspopup="true">*/}
{/* <span class="sr-only">Open options menu</span>*/}
{/* <span class="flex h-full w-full items-center justify-center rounded-full">*/}
{/* <svg class="h-5 w-5 text-gray-400 group-hover:text-gray-500"*/}
{/* xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor"*/}
{/* aria-hidden="true">*/}
{/* <path*/}
{/* d="M10 3a1.5 1.5 0 110 3 1.5 1.5 0 010-3zM10 8.5a1.5 1.5 0 110 3 1.5 1.5 0 010-3zM11.5 15.5a1.5 1.5 0 10-3 0 1.5 1.5 0 003 0z"/>*/}
{/* </svg>*/}
{/*</span>*/}
{/* </button>*/}
{/*<div*/}
{/* class="absolute top-0 right-9 z-10 w-48 origin-top-right rounded-md bg-white shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none"*/}
{/* role="menu" aria-orientation="vertical" aria-labelledby="options-menu-0-button"*/}
{/* >*/}
<button onClick={() => this.deleteNotif(notif.id)}>
<svg class="h-6 w-6" xmlns="http://www.w3.org/2000/svg" fill="none"
viewBox="0 0 24 24"
stroke-width="1.5" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/>
</svg></button>
</svg>
</button>
</div>
</div>
</li>*/
<li>
<div class="border-b group relative flex items-center py-6 px-5">
<a href="#" class="-m-1 block flex-1 p-1">
<div class="relative flex min-w-0 flex-1 items-center">
<span class="relative inline-block flex-shrink-0">
<svg class="h-6 w-6 text-green-400 z-30" xmlns="http://www.w3.org/2000/svg" fill="none"
viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round"
d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
</span>
<div class="ml-4 truncate">
<p class="truncate text-sm font-medium text-gray-900">{notif.title}</p>
<p class="truncate text-sm text-gray-500">{notif.text}</p>
</div>
</div>
</a>
<div class="relative ml-2 inline-block flex-shrink-0 text-left">
<button onClick={() => this.deleteNotif(notif.id)}>
<svg class="h-6 w-6" xmlns="http://www.w3.org/2000/svg" fill="none"
viewBox="0 0 24 24"
stroke-width="1.5" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/>
</svg>
</button>
{/*</div>*/}
</div>
</div>
</li>
))}
))}
</ul>
</div>
</div>
</div>
</div>
);
}
}

View file

@ -1,22 +1,25 @@
import notificationStore from "./notification-store";
import {NotificationType} from "./models"
export class NotificationService {
export default class NotificationService {
constructor() {
}
static toogleNotification = () => {
notificationStore.infoPanelBoolean = !notificationStore.infoPanelBoolean
}
static createNotification = (notification: NotificationType ): NotificationType => {
notificationStore.notifications = [...notificationStore.notifications, notification]
return notification;
}
static updateNotification = (notification: NotificationType, obj: NotificationType) => {
console.log(notification);
static updateNotification = (notification: NotificationType, newNotifFields: NotificationType) => {
const notifIndex = notificationStore.notifications.findIndex(item => item.id === notification.id)
const notif = notificationStore.notifications.find(item => item.id === notification.id)
notif.title = obj.title;
notif.text = obj.text;
notif.title = newNotifFields.title;
notif.text = newNotifFields.text;
const filtered = notificationStore.notifications.filter(item => item.id !== notification.id)
notificationStore.notifications = [...filtered, notificationStore.notifications[notifIndex] = notif]

View file

@ -2,6 +2,7 @@ import { createStore } from '@stencil/store';
const { state, onChange } = createStore({
notifications: [],
infoPanelBoolean: false,
});
export default state;

View file

@ -21,7 +21,7 @@ import {ExportWorkflowRequest, ImportWorkflowRequest, WorkflowDefinitionsApi} fr
import {DefaultModalActions, ModalDialogInstance, ModalDialogService} from "../../components/shared/modal-dialog";
import {isEqual} from 'lodash'
import {htmlToElement, isNullOrWhitespace} from "../../utils";
import {NotificationService} from "../notifications/notification-service";
import NotificationService from "../notifications/notification-service";
import {uuid} from "@antv/x6/es/util/string/uuid";
const FlowchartTypeName = 'Elsa.Flowchart';