diff --git a/projects/valtimo/process-link/src/lib/components/form-link-process-diagram/form-link-process-diagram.component.ts b/projects/valtimo/process-link/src/lib/components/form-link-process-diagram/form-link-process-diagram.component.ts index 8feafae10..81d1257c5 100644 --- a/projects/valtimo/process-link/src/lib/components/form-link-process-diagram/form-link-process-diagram.component.ts +++ b/projects/valtimo/process-link/src/lib/components/form-link-process-diagram/form-link-process-diagram.component.ts @@ -30,7 +30,6 @@ import {ActivatedRoute} from '@angular/router'; import {combineLatest} from 'rxjs'; import {map} from 'rxjs/operators'; import {PageTitleService} from '@valtimo/components'; -import {ValtimoRenderer} from '../../services/valtimo-renderer'; @Component({ selector: 'valtimo-form-link-process-diagram', @@ -82,17 +81,7 @@ export class FormLinkProcessDiagramComponent implements OnInit, OnDestroy { this.loadProcessDefinitionFromKey(this.processDefinitionKey); } }); - this.bpmnViewer = new BpmnViewer({ - valtimoRenderer: { - test: 'test', - }, - additionalModules: [ - { - __init__: ['ValtimoRenderer'], - ValtimoRenderer: ['type', ValtimoRenderer], - }, - ], - }); + this.bpmnViewer = new BpmnViewer({}); this.bpmnViewer.on('import.done', ({error}: any) => { if (!error) { const canvas = this.bpmnViewer.get('canvas') as any; diff --git a/projects/valtimo/process-link/src/lib/components/process-link/process-link.component.ts b/projects/valtimo/process-link/src/lib/components/process-link/process-link.component.ts index 801ac61cc..66bb65396 100644 --- a/projects/valtimo/process-link/src/lib/components/process-link/process-link.component.ts +++ b/projects/valtimo/process-link/src/lib/components/process-link/process-link.component.ts @@ -64,19 +64,12 @@ export class ProcessLinkComponent { const processLink = result.processLink; this.stateService.setModalParams(params); - - console.log('set modal params in state service', params); - this.stateService.setElementName(params?.element?.name); - console.log('set element name data', params?.element?.name); - if (processLink) { this.stateService.selectProcessLink(processLink); - console.log('set process link', processLink); } else { this.stateService.setAvailableProcessLinkTypes(result); - console.log('set available links', result); } if (result?.length > 0 || processLink) { diff --git a/projects/valtimo/process-link/src/lib/services/valtimo-renderer.ts b/projects/valtimo/process-link/src/lib/services/valtimo-renderer.ts deleted file mode 100644 index 561c62a60..000000000 --- a/projects/valtimo/process-link/src/lib/services/valtimo-renderer.ts +++ /dev/null @@ -1,76 +0,0 @@ -import BaseRenderer from 'diagram-js/lib/draw/BaseRenderer'; -import {is, isAny} from 'bpmn-js/lib/util/ModelUtil'; -import {append as svgAppend, create as svgCreate} from 'tiny-svg'; -import {black} from 'bpmn-js/lib/draw/BpmnRenderUtil'; -import BpmnRenderer from 'bpmn-js/lib/draw/BpmnRenderer'; -import Styles from 'diagram-js/lib/draw/Styles'; -import {zakenApiPluginSpecification} from '@valtimo/plugin'; -import EventBus from 'diagram-js/lib/core/EventBus'; - -export class ValtimoRenderer extends BaseRenderer { - test: string; - - constructor( - private eventBus: EventBus, - private styles: Styles, - private bpmnRenderer: BpmnRenderer, - private config: any - ) { - console.log('init', arguments) - super(eventBus, 1500); - - this.test = config && config.valtimoRenderer.test - } - - canRender(element) { - - console.log('canRender') - - // only render tasks and events (ignore labels) - return isAny(element, [ 'bpmn:Task' ]) && !element.labelTarget; - } - - drawShape(parentNode, element) { - const shape = this.bpmnRenderer.drawShape(parentNode, element); - - console.log('drawShape') - - if (is(element, 'bpmn:Task')) { - const pluginImageUrl = zakenApiPluginSpecification.pluginLogoBase64 - const img = this.drawImage(parentNode, pluginImageUrl, 30, 30, { - x: 68, - }) - return shape; - } - - return shape; - } - - drawImage(parentGfx, imgSource, width, height, attrs = {}): SVGElement { - - attrs = this.shapeStyle(attrs); - - var image = svgCreate('image', { - href: imgSource, - width: width, - height: height, - ...attrs - }) as SVGElement; - - svgAppend(parentGfx, image); - - return image; - } - - // copied from https://github.com/bpmn-io/bpmn-js/blob/master/lib/draw/BpmnRenderer.js - shapeStyle(attrs) { - return this.styles.computeStyle(attrs, { - strokeLinecap: 'round', - strokeLinejoin: 'round', - stroke: black, - strokeWidth: 2, - fill: 'white' - }); - } -} - diff --git a/projects/valtimo/process-link/src/public-api.ts b/projects/valtimo/process-link/src/public-api.ts index 9cd729ead..91c392f84 100644 --- a/projects/valtimo/process-link/src/public-api.ts +++ b/projects/valtimo/process-link/src/public-api.ts @@ -19,7 +19,6 @@ */ export * from './lib/services'; -export * from './lib/services/valtimo-renderer'; export * from './lib/components/select-plugin-configuration/select-plugin-configuration.component'; export * from './lib/components/select-plugin-action/select-plugin-action.component'; export * from './lib/components/select-url/select-url.component'; diff --git a/projects/valtimo/process-management/src/lib/components/index.ts b/projects/valtimo/process-management/src/lib/components/index.ts index 6f5e023c5..f7e935d86 100644 --- a/projects/valtimo/process-management/src/lib/components/index.ts +++ b/projects/valtimo/process-management/src/lib/components/index.ts @@ -15,7 +15,6 @@ */ export * from './process-management'; -export * from './process-management-editor'; export * from './process-management-builder'; export * from './process-management-list'; export * from './process-management-upload'; diff --git a/projects/valtimo/process-management/src/lib/components/process-management-builder/customizer/index.ts b/projects/valtimo/process-management/src/lib/components/process-management-builder/customizer/index.ts deleted file mode 100644 index eaf344e20..000000000 --- a/projects/valtimo/process-management/src/lib/components/process-management-builder/customizer/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -import {PropertyPanelCustomizer} from './property-panel-customizer'; - -export default { - __init__: [ 'valtimoPropertiesProvider' ], - valtimoPropertiesProvider: [ 'type', PropertyPanelCustomizer ] -}; diff --git a/projects/valtimo/process-management/src/lib/components/process-management-builder/customizer/property-panel-customizer.ts b/projects/valtimo/process-management/src/lib/components/process-management-builder/customizer/property-panel-customizer.ts deleted file mode 100644 index 5407dbea4..000000000 --- a/projects/valtimo/process-management/src/lib/components/process-management-builder/customizer/property-panel-customizer.ts +++ /dev/null @@ -1,126 +0,0 @@ -import {PropertiesPanel} from 'bpmn-js-properties-panel'; -import {isTextFieldEntryEdited} from '@bpmn-io/properties-panel'; -import {html} from 'htm/preact'; -import {ModalService} from '@valtimo/components'; -import {tap} from 'rxjs'; -import {ProcessLinkService, ProcessLinkStateService} from '@valtimo/process-link'; -import {ProcessLinks} from '../../../process-management.service'; - -export class PropertyPanelCustomizer { - private LOW_PRIORITY = 500; - - public static $inject = ['propertiesPanel', 'translate']; - - constructor( - private readonly propertiesPanel: PropertiesPanel, - private readonly translate: Function, - private readonly modalService: ModalService - ) { - propertiesPanel.registerProvider(this.LOW_PRIORITY, this); - } - - public getGroups(element) { - /** - * We return a middleware that modifies - * the existing groups. - * - * @param {Object[]} groups - * - * @return {Object[]} modified groups - */ - const parent = this; - return function (groups) { - console.log('groups', groups); - for (let i = 0; i < groups.length; i++) { - if ( - groups[i].id === 'CamundaPlatform__Implementation' || - groups[i].id === 'CamundaPlatform__Form' - ) { - console.log('entries', groups[i].entries); - for (let j = 0; j < groups[i].entries.length; j++) { - if (groups[i].entries[j].id === 'implementationType') { - groups[i].entries[j].component.getOptions = function () { - return [ - {value: '', label: 'test 1'}, - {value: '2', label: 'test 2'}, - ]; - }; - } - } - - groups[i].entries.push({ - id: 'linkProcessButton', - element, - component: parent.ProcessLink, - isEdited: isTextFieldEntryEdited, - }); - } - } - - return groups; - }; - } - - private ProcessLink(element: any, id: any) { - console.log('element', element); - console.log('id', id); - - const modalService = (window as any).modalService as ModalService; - const stateService = (window as any).stateService as ProcessLinkStateService; - const processLinkService = (window as any).processLinkService as ProcessLinkService; - const processLinks = (window as any).processLinks as ProcessLinks; - - const processLinkForElement = processLinks.processLinks$.value.find( - processLink => processLink.activityId === element.element.id - ); - - console.log('processLinkForElement', processLinkForElement); - - const openModal = () => { - var activityListenerType = element?.element?.type; - if (activityListenerType === 'bpmn:UserTask') { - activityListenerType = activityListenerType + ':create'; - } else { - activityListenerType = activityListenerType + ':start'; - } - - modalService.setModalData({ - id: element.element.businessObject.id, - type: element.element.businessObject.$type, - activityListenerType, - name: element.element?.businessObject?.name, - }); - - if (activityListenerType) { - processLinkService - .getProcessLinkCandidates(activityListenerType) - .pipe( - tap(res => { - stateService.setModalParams(element); - stateService.setElementName(element?.element?.name); - - if (processLinkForElement) { - stateService.selectProcessLink(processLinkForElement); - } else { - stateService.setAvailableProcessLinkTypes(res); - } - - if (res?.length > 0) { - stateService.showModal(); - } - }) - ) - .subscribe(); - } - }; - - if (processLinkForElement) { - return html`
- -
`; - } - return html`
- -
`; - } -} diff --git a/projects/valtimo/process-management/src/lib/components/process-management-builder/index.ts b/projects/valtimo/process-management/src/lib/components/process-management-builder/index.ts index 54c66a30a..419d408e5 100644 --- a/projects/valtimo/process-management/src/lib/components/process-management-builder/index.ts +++ b/projects/valtimo/process-management/src/lib/components/process-management-builder/index.ts @@ -14,5 +14,4 @@ * limitations under the License. */ -export * from './customizer'; export * from './process-management-builder.component'; diff --git a/projects/valtimo/process-management/src/lib/components/process-management-editor/panel/index.ts b/projects/valtimo/process-management/src/lib/components/process-management-builder/panel/index.ts similarity index 100% rename from projects/valtimo/process-management/src/lib/components/process-management-editor/panel/index.ts rename to projects/valtimo/process-management/src/lib/components/process-management-builder/panel/index.ts diff --git a/projects/valtimo/process-management/src/lib/components/process-management-editor/panel/valtimo-properties-provider.ts b/projects/valtimo/process-management/src/lib/components/process-management-builder/panel/valtimo-properties-provider.ts similarity index 100% rename from projects/valtimo/process-management/src/lib/components/process-management-editor/panel/valtimo-properties-provider.ts rename to projects/valtimo/process-management/src/lib/components/process-management-builder/panel/valtimo-properties-provider.ts diff --git a/projects/valtimo/process-management/src/lib/components/process-management-builder/process-management-builder.component.html b/projects/valtimo/process-management/src/lib/components/process-management-builder/process-management-builder.component.html index 147170ae9..eb3f819ba 100644 --- a/projects/valtimo/process-management/src/lib/components/process-management-builder/process-management-builder.component.html +++ b/projects/valtimo/process-management/src/lib/components/process-management-builder/process-management-builder.component.html @@ -14,123 +14,103 @@ ~ limitations under the License. --> -
-
-
-
- - - -
-
+
+
+ +
-
-
-
- - {{ 'processManagement.readOnly' | translate }} - - - {{ 'processManagement.systemProcess' | translate }} - -
-
- - + +
-
-
- - - -
-
-
- + +
+ {{ + 'processManagement.readOnly' | translate + }} + + {{ + 'processManagement.systemProcess' | translate + }}
-
-
-
-
-
-
+ +
+ + {{ 'interface.export' | translate }} + + +
-
-
- - + + diff --git a/projects/valtimo/process-management/src/lib/components/process-management-builder/process-management-builder.component.scss b/projects/valtimo/process-management/src/lib/components/process-management-builder/process-management-builder.component.scss index 9b69e6608..22530d361 100644 --- a/projects/valtimo/process-management/src/lib/components/process-management-builder/process-management-builder.component.scss +++ b/projects/valtimo/process-management/src/lib/components/process-management-builder/process-management-builder.component.scss @@ -14,41 +14,87 @@ * limitations under the License. */ -$border: 1px solid #dee2e6; +.bpmn { + &__container { + position: relative; + background-color: var(--cds-layer); + width: 100%; + } -.versions { - border: $border; -} + &__modeler { + width: 100%; + height: 100%; + flex-direction: row; + padding: 1px; + box-sizing: border-box; + outline: 1px solid var(--cds-border-subtle); + outline-offset: -1px; -.diagram { - border: $border; -} + // hide blue focus border bpmn + ::ng-deep .djs-container > svg { + outline: none !important; + } + } -.process-title { - color: #6b6b6b; - font-size: 1.5rem; -} + &__modeler-canvas { + width: 100%; + } -.fullscreen-toggle { - font-size: 2rem; - > i { - cursor: pointer; + &__modeler-panel { + width: 481px; + padding-left: 1px; + box-shadow: inset 1px 0 0 0 var(--cds-border-subtle); + box-sizing: border-box; } -} -.modeler { - height: 90vh; + &__loading { + width: 100%; + height: 100%; + display: flex; + justify-content: center; + align-items: center; + background-color: var(--cds-background-selected); + } } -.select-version-control { - width: 90px; -} +.page-header-actions { + display: flex; + width: 100%; + justify-content: space-between; -#properties { - border-left: $border; - padding-left: 0; + &__left-container { + display: flex; + gap: 24px; + align-items: flex-end; + } + + &__tags { + display: flex; + gap: 8px; + align-items: flex-end; + } + + &__version-dropdown { + width: 150px; + } + + &__buttons { + display: flex; + gap: 16px; + } } -#readOnlyCanvas { - height: 90vh; +::ng-deep .process-link-properties-panel { + padding: 8px 12px 16px 12px; + width: 100%; + display: flex; + flex-direction: row; + gap: 16px; + + .cds--btn { + flex-shrink: 1; + width: 100%; + display: flex; + align-items: center; + } } diff --git a/projects/valtimo/process-management/src/lib/components/process-management-builder/process-management-builder.component.ts b/projects/valtimo/process-management/src/lib/components/process-management-builder/process-management-builder.component.ts index 0d3d4d385..773bbde21 100644 --- a/projects/valtimo/process-management/src/lib/components/process-management-builder/process-management-builder.component.ts +++ b/projects/valtimo/process-management/src/lib/components/process-management-builder/process-management-builder.component.ts @@ -14,201 +14,469 @@ * limitations under the License. */ -import {Component, OnDestroy, OnInit, ViewEncapsulation} from '@angular/core'; -import {HttpClient} from '@angular/common/http'; -import {ProcessDefinition, ProcessService} from '@valtimo/process'; -import {AlertService, ModalService, PageTitleService} from '@valtimo/components'; +import {AfterViewInit, Component, ElementRef, OnDestroy, ViewChild} from '@angular/core'; +import {CommonModule} from '@angular/common'; +import { + CARBON_CONSTANTS, + FitPageDirectiveModule, + ModalService, + PageHeaderService, + PageTitleService, + RenderInPageHeaderDirectiveModule, +} from '@valtimo/components'; import {ActivatedRoute, Router} from '@angular/router'; -import {BehaviorSubject, forkJoin, Observable} from 'rxjs'; -import {LayoutService} from '@valtimo/layout'; +import { + BehaviorSubject, + combineLatest, + filter, + from, + map, + Observable, + startWith, + Subject, + Subscription, + switchMap, + take, + tap, +} from 'rxjs'; +import {ProcessDefinition, ProcessService} from '@valtimo/process'; +import { + ButtonModule, + DialogModule, + DropdownModule, + IconModule, + IconService, + ListItem, + LoadingModule, + NotificationModule, + NotificationService, + SelectModule, + TagModule, +} from 'carbon-components-angular'; import Modeler from 'bpmn-js/lib/Modeler'; -import BpmnViewer from 'bpmn-js'; +import NavigatedViewer from 'bpmn-js/lib/NavigatedViewer'; +import {ReactiveFormsModule} from '@angular/forms'; +import {TranslateModule, TranslateService} from '@ngx-translate/core'; +import {Deploy16, Download16} from '@carbon/icons'; import { BpmnPropertiesPanelModule, BpmnPropertiesProviderModule, CamundaPlatformPropertiesProviderModule, } from 'bpmn-js-properties-panel'; -import CamundaBpmnModdle from 'camunda-bpmn-moddle/resources/camunda.json'; import camundaPlatformBehaviors from 'camunda-bpmn-js-behaviors/lib/camunda-platform'; -import magicPropertiesProviderModule from './customizer'; -import {ProcessLinkService, ProcessLinkStateService} from '@valtimo/process-link'; -import {ProcessManagementService} from '../../process-management.service'; +import CamundaBpmnModdle from 'camunda-bpmn-moddle/resources/camunda.json'; +import {ValtimoPropertiesProviderModule} from './panel'; +import {distinctUntilChanged} from 'rxjs/operators'; +import {isEqual} from 'lodash'; +import {ProcessManagementEditorService} from '../../services'; +import {OpenProcessLinkModalEvent, ProcessManagementWindow} from '../../models'; +import { + ProcessLinkButtonService, + ProcessLinkCreateEvent, + ProcessLinkEditMode, + ProcessLinkModule, + ProcessLinkService, + ProcessLinkStateService, + ProcessLinkStepService, +} from '@valtimo/process-link'; +import {EMPTY_BPMN} from '../../constants'; @Component({ selector: 'valtimo-process-management-builder', templateUrl: './process-management-builder.component.html', styleUrls: ['./process-management-builder.component.scss'], - encapsulation: ViewEncapsulation.None, + standalone: true, + imports: [ + CommonModule, + FitPageDirectiveModule, + LoadingModule, + RenderInPageHeaderDirectiveModule, + DropdownModule, + ReactiveFormsModule, + SelectModule, + ButtonModule, + IconModule, + TranslateModule, + TagModule, + ProcessLinkModule, + ProcessLinkModule, + DialogModule, + NotificationModule, + ], + providers: [ + ProcessManagementEditorService, + ProcessLinkStateService, + ProcessLinkStepService, + ProcessLinkButtonService, + NotificationService, + ], }) -export class ProcessManagementBuilderComponent implements OnInit, OnDestroy { - public bpmnModeler; - public bpmnViewer; - public processDefinitionVersions: ProcessDefinition[] | null = null; - public selectedVersion: ProcessDefinition | null = null; - public processKey: string | null = null; +export class ProcessManagementBuilderComponent implements AfterViewInit, OnDestroy { + @ViewChild('modeler', {static: false}) modelerElementRef!: ElementRef; + @ViewChild('modelerPanel', {static: false}) modelerPanelElementRef!: ElementRef; + @ViewChild('viewer', {static: false}) viewerElementRef!: ElementRef; + @ViewChild('viewerPanel', {static: false}) viewerPanelElementRef!: ElementRef; + + public readonly loading$ = new BehaviorSubject(true); + + private _bpmnModeler!: Modeler; + private _bpmnViewer!: NavigatedViewer; + public isReadOnlyProcess$ = new BehaviorSubject(false); public isSystemProcess$ = new BehaviorSubject(false); - private elementTemplateFiles: string[] = ['mailSendTask']; + + public readonly selectedProcessDefinitionXml$ = + this.processManagementEditorService.selectionProcessDefinition$.pipe( + filter(selectedProcessDefinition => !!selectedProcessDefinition?.id), + distinctUntilChanged((previous, current) => isEqual(previous, current)), + tap(selectedProcessDefinition => { + this.loading$.next(true); + this.pageTitleService.setCustomPageTitle(selectedProcessDefinition.name); + }), + switchMap(selectedProcessDefinition => + this.processService.getProcessDefinitionXml(selectedProcessDefinition.id) + ), + tap(result => { + this._bpmnModeler?.importXML(result.bpmn20Xml); + this._bpmnViewer?.importXML(result.bpmn20Xml); + this.isReadOnlyProcess$.next(result.readOnly); + this.isSystemProcess$.next(result.systemProcess); + this.loading$.next(false); + }) + ); + + private readonly _processDefinitionKey$ = this.route.params.pipe( + map(params => params.key), + filter(key => !!key) + ); + + private readonly _reload$ = new Subject(); + + public readonly changesPending$ = new BehaviorSubject(false); + + public readonly processDefinitionVersions$ = combineLatest([ + this._processDefinitionKey$, + this._reload$.pipe(startWith(null)), + ]).pipe( + switchMap(([processDefinitionKey]) => + this.processService.getProcessDefinitionVersions(processDefinitionKey) + ), + tap(processDefinitions => { + this.changesPending$.next(false); + this.setSelectedProcessDefinitionToLatest(processDefinitions); + }) + ); + + public readonly processDefinitionVersionsListItems$: Observable = combineLatest([ + this.processDefinitionVersions$, + this.processManagementEditorService.selectionProcessDefinition$, + this.translateService.stream('key'), + ]).pipe( + map(([processDefinitionVersions, selectionProcessDefinition]) => + processDefinitionVersions + .map(processDefinitionVersion => ({ + id: processDefinitionVersion.version, + content: `${this.translateService.instant('processManagement.version')}${processDefinitionVersion.version}`, + selected: selectionProcessDefinition.version === processDefinitionVersion.version, + processDefinitionVersion, + })) + .sort((a, b) => b.id - a.id) + ) + ); + + public readonly compactMode$ = this.pageHeaderService.compactMode$; + + public readonly creatingNewProcess$ = new BehaviorSubject(false); + + private readonly _subscriptions = new Subscription(); constructor( - private readonly http: HttpClient, - private readonly processService: ProcessService, - public readonly layoutService: LayoutService, - private readonly alertService: AlertService, private readonly route: ActivatedRoute, - private readonly router: Router, + private readonly processService: ProcessService, private readonly pageTitleService: PageTitleService, - + private readonly translateService: TranslateService, + private readonly iconService: IconService, + private readonly pageHeaderService: PageHeaderService, + private readonly processManagementEditorService: ProcessManagementEditorService, private readonly modalService: ModalService, - private readonly stateService: ProcessLinkStateService, private readonly processLinkService: ProcessLinkService, - private readonly processManagementService: ProcessManagementService + private readonly processLinkStateService: ProcessLinkStateService, + private readonly router: Router, + private readonly notificationService: NotificationService ) { - (window as any).modalService = modalService; - (window as any).stateService = stateService; - (window as any).processLinkService = processLinkService; + this.iconService.registerAll([Deploy16, Download16]); + (window as any as ProcessManagementWindow).processManagementEditorService = + processManagementEditorService; + (window as any as ProcessManagementWindow).translateService = translateService; } - ngOnInit() { - this.init(); + public ngAfterViewInit(): void { + this.initModeler(); + this.initViewer(); + this.subscribeToOpenProcessLinkModalEvents(); + this.subscribeToProcessLinkUpdateEvents(); + this.subscribeToProcessLinkCreateEvents(); + this.subscribeToProcessLinkDeleteEvents(); + this.processLinkStateService.setEditMode(ProcessLinkEditMode.EMIT_EVENTS); + this.initIfCreate(); } - init() { - this.processKey = this.route.snapshot.paramMap.get('key'); - forkJoin(this.getElementTemplates()).subscribe((elementTemplates: any[]) => { - this.bpmnModeler = new Modeler({ - container: '#canvas', - height: '90vh', - valtimoRenderer: { - test: 'test', - }, - additionalModules: [ - BpmnPropertiesPanelModule, - BpmnPropertiesProviderModule, - CamundaPlatformPropertiesProviderModule, - camundaPlatformBehaviors, - magicPropertiesProviderModule, - ], - propertiesPanel: { - parent: '#properties', - }, - moddleExtensions: { - camunda: CamundaBpmnModdle, - }, - elementTemplates, + public ngOnDestroy(): void { + this._bpmnModeler?.destroy(); + this._bpmnViewer?.destroy(); + this._subscriptions.unsubscribe(); + } + + public deployChanges(isReadOnlyProcess: boolean): void { + combineLatest([ + isReadOnlyProcess ? from(this._bpmnViewer.saveXML()) : from(this._bpmnModeler.saveXML()), + this.processManagementEditorService.processLinksForSelectedDefinition$, + this.processManagementEditorService.selectionProcessDefinition$, + ]) + .pipe( + take(1), + switchMap(([result, processLinks, selectedProcessDefinition]) => + this.processLinkService.deployProcessWithProcessLinks( + processLinks as ProcessLinkCreateEvent[], + selectedProcessDefinition.id, + !isReadOnlyProcess ? result.xml : null + ) + ) + ) + .subscribe(() => { + this.reload(); }); - this.bpmnViewer = new BpmnViewer(); - this.bpmnViewer.attachTo('#readOnlyCanvas'); - if (this.processKey) { - this.loadProcessVersions(this.processKey); - this.selectedVersion = null; - } else { - this.loadEmptyBpmn(); - } - }); } - deploy(): void { - this.bpmnModeler.saveXML((err: any, xml: any) => { - this.processService.deployProcess(xml).subscribe(asd => { - if (this.processKey) { - this.loadProcessVersions(this.processKey); - } else { - this.router.navigate(['/processes']); + public deployNewProcessDefinition(): void { + combineLatest([ + from(this._bpmnModeler.saveXML()), + this.processManagementEditorService.processLinksForSelectedDefinition$, + ]) + .pipe( + take(1), + switchMap(([result, processLinks]) => + this.processLinkService.deployProcessWithProcessLinks( + processLinks.map(link => ({ + ...link, + processDefinitionId: '-', + })) as ProcessLinkCreateEvent[], + null, + result.xml + ) + ) + ) + .subscribe(() => { + this.router.navigate(['/processes']); + this.notificationService.showToast({ + caption: this.translateService.instant('formFlow.savedSuccessTitleMessage'), + type: 'success', + duration: CARBON_CONSTANTS.notificationDuration, + showClose: true, + title: this.translateService.instant('formFlow.savedSuccessTitle'), + }); + }); + } + + public export(isReadOnlyProcess: boolean): void { + (isReadOnlyProcess ? from(this._bpmnViewer.saveXML()) : from(this._bpmnModeler.saveXML())) + .pipe(take(1)) + .subscribe(result => { + const file = new Blob([result.xml], {type: 'text/xml'}); + const link = document.createElement('a'); + link.download = 'diagram.bpmn'; + link.href = window.URL.createObjectURL(file); + link.click(); + window.URL.revokeObjectURL(link.href); + link.remove(); + }); + } + + public selectedVersionChange(event: {item: {processDefinitionVersion: ProcessDefinition}}): void { + this.processManagementEditorService.selectionProcessDefinition$ + .pipe(take(1)) + .subscribe(selectedVersion => { + if (selectedVersion.id !== event.item.processDefinitionVersion.id) { + this.processManagementEditorService.setSelectedProcessDefinition( + event?.item?.processDefinitionVersion + ); + this.changesPending$.next(false); } - this.alertService.success('Deployment successful'); - this.selectedVersion = null; }); - }); } - reset() { - this.bpmnModeler.destroy(); - this.bpmnViewer.destroy(); - this.init(); + private setSelectedProcessDefinitionToLatest(processDefinitions: ProcessDefinition[]): void { + this.processManagementEditorService.setSelectedProcessDefinition( + processDefinitions.reduce((acc, version) => (version.version > acc.version ? version : acc)) + ); } - download() { - this.bpmnModeler.saveXML((err: any, xml: any) => { - const file = new Blob([xml], {type: 'text/xml'}); - const link = document.createElement('a'); - link.download = 'diagram.bpmn'; - link.href = window.URL.createObjectURL(file); - link.click(); - window.URL.revokeObjectURL(link.href); - link.remove(); + private initModeler(): void { + this._bpmnModeler = new Modeler({ + additionalModules: [ + BpmnPropertiesPanelModule, + BpmnPropertiesProviderModule, + CamundaPlatformPropertiesProviderModule, + camundaPlatformBehaviors, + ValtimoPropertiesProviderModule, + ], + moddleExtensions: { + camunda: CamundaBpmnModdle, + }, + propertiesPanel: { + parent: this.modelerPanelElementRef.nativeElement, + }, + }); + + this._bpmnModeler?.attachTo(this.modelerElementRef.nativeElement); + + this._bpmnModeler.on('commandStack.changed', () => { + this.changesPending$.next(true); }); } - loadEmptyBpmn() { - const url = '/assets/bpmn/initial.bpmn'; - this.http - .get(url, { - headers: {observe: 'response'}, - responseType: 'text', - }) - .subscribe((xml: any) => { - this.bpmnModeler.importXML(xml); - this.bpmnViewer.importXML(xml); - }); + private initViewer(): void { + const disableCommands = () => { + const commandStack = this._bpmnViewer.get('commandStack') as any; + const originalExecute = commandStack?.execute?.bind(commandStack); + + if (commandStack?.execute) { + commandStack.execute = (command: string, context: any) => { + if ( + command === 'elements.delete' || + command === 'elements.copy' || + command === 'elements.paste' || + command === 'elements.create' + ) { + return; + } + originalExecute(command, context); + }; + } + }; + + const DisableBpmnWriteModule = { + paletteProvider: ['value', {}], + contextPadProvider: ['value', {}], + directEditing: [ + 'value', + { + registerProvider: () => {}, + activate: () => {}, + deactivate: () => {}, + isActive: () => false, + }, + ], + move: ['value', null], + resizeHandles: [ + 'value', + { + addResizer: () => {}, + removeResizers: () => {}, + }, + ], + }; + + this._bpmnViewer = new Modeler({ + additionalModules: [ + DisableBpmnWriteModule, + BpmnPropertiesPanelModule, + ValtimoPropertiesProviderModule, + ], + moddleExtensions: { + camunda: CamundaBpmnModdle, + }, + propertiesPanel: { + parent: this.viewerPanelElementRef.nativeElement, + }, + }); + + this._bpmnViewer?.attachTo(this.viewerElementRef.nativeElement); + + this._bpmnViewer.on('import.done', () => { + disableCommands(); + }); + + this._bpmnViewer.on('commandStack.changed', () => { + this.changesPending$.next(true); + }); } - getElementTemplates(): Observable[] { - const templateObs = []; - for (const file of this.elementTemplateFiles) { - templateObs.push( - this.http.get(`/assets/bpmn/element-templates/${file}.json`, { - headers: {observe: 'response'}, - responseType: 'json', - }) - ); - } - return templateObs; + private reload(): void { + this._reload$.next(null); } - private setLatestVersion() { - this.selectedVersion = this.processDefinitionVersions.reduce((acc, version) => - version.version > acc.version ? version : acc - ); - this.loadProcessBpmn(); - (window as any).processLinks = this.processManagementService.getProcessLinks( - this.selectedVersion.id - ); + private handleUpdateEvent(event: OpenProcessLinkModalEvent): void { + this.modalService.setModalData(event?.modalParams); + this.processLinkStateService.setModalParams(event?.modalParams); + this.processLinkStateService.setElementName(event?.modalParams?.element?.name); + this.processLinkStateService.selectProcessLink(event.processLink); + this.processLinkStateService.showModal(); } - loadProcessVersions(processDefinitionKey: string) { - this.processService - .getProcessDefinitionVersions(processDefinitionKey) - .subscribe((processDefinitionVersions: ProcessDefinition[]) => { - this.processDefinitionVersions = processDefinitionVersions; - this.pageTitleService.setCustomPageTitle( - processDefinitionVersions[processDefinitionVersions.length - 1].name - ); - this.setLatestVersion(); + private handleCreateEvent(event: OpenProcessLinkModalEvent): void { + this.processLinkService + .getProcessLinkCandidates(event.modalParams.element.activityListenerType) + .subscribe(candidates => { + this.modalService.setModalData(event?.modalParams); + this.processLinkStateService.setModalParams(event?.modalParams); + this.processLinkStateService.setElementName(event?.modalParams?.element?.name); + this.processLinkStateService.setAvailableProcessLinkTypes(candidates); + this.processLinkStateService.showModal(); }); } - compareProcessDefinitions(pd1: ProcessDefinition, pd2: ProcessDefinition) { - if (pd1 === null && pd2 === null) { - return true; - } - if (pd1 === null || pd2 === null) { - return false; - } - return pd1.id === pd2.id; + private subscribeToOpenProcessLinkModalEvents(): void { + this._subscriptions.add( + this.processManagementEditorService.openProcessLinkModalEvents$.subscribe(event => { + if (event.processLink) { + this.handleUpdateEvent(event); + } else { + this.handleCreateEvent(event); + } + }) + ); } - loadProcessBpmn() { - this.processService.getProcessDefinitionXml(this.selectedVersion.id).subscribe(result => { - this.bpmnModeler.importXML(result['bpmn20Xml']); - this.bpmnViewer.importXML(result['bpmn20Xml']); - this.isReadOnlyProcess$.next(result.readOnly); - this.isSystemProcess$.next(result.systemProcess); - }); + private subscribeToProcessLinkUpdateEvents(): void { + this._subscriptions.add( + this.processLinkStateService.processLinkUpdateEvents$.subscribe(event => { + this.processManagementEditorService.updateProcessLink(event); + this.processLinkStateService.stopSaving(); + this.processLinkStateService.closeModal(); + }) + ); } - ngOnDestroy() { - this.bpmnModeler.destroy(); - this.bpmnViewer.destroy(); + private subscribeToProcessLinkCreateEvents(): void { + this._subscriptions.add( + this.processLinkStateService.processLinkCreateEvents$.subscribe(event => { + this.processManagementEditorService.createProcessLink(event); + this.processLinkStateService.stopSaving(); + this.processLinkStateService.closeModal(); + }) + ); + } + + private subscribeToProcessLinkDeleteEvents(): void { + this._subscriptions.add( + this.processLinkStateService.processLinkDeleteEvents$.subscribe(event => { + this.processManagementEditorService.deleteProcessLink(event); + this.processLinkStateService.stopSaving(); + this.processLinkStateService.closeModal(); + }) + ); + } + + private initIfCreate(): void { + const currentUrl = this.route.snapshot.url.toString(); + + if (!currentUrl.includes('create')) return; + + this.creatingNewProcess$.next(true); + this._bpmnModeler?.importXML(EMPTY_BPMN); + this.isReadOnlyProcess$.next(false); + this.isSystemProcess$.next(false); + this.loading$.next(false); } } diff --git a/projects/valtimo/process-management/src/lib/components/process-management-editor/index.ts b/projects/valtimo/process-management/src/lib/components/process-management-editor/index.ts deleted file mode 100644 index ca8a39b00..000000000 --- a/projects/valtimo/process-management/src/lib/components/process-management-editor/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2015-2024 Ritense BV, the Netherlands. - * - * Licensed under EUPL, Version 1.2 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export * from './process-management-editor.component'; diff --git a/projects/valtimo/process-management/src/lib/components/process-management-editor/process-management-editor.component.html b/projects/valtimo/process-management/src/lib/components/process-management-editor/process-management-editor.component.html deleted file mode 100644 index eb3f819ba..000000000 --- a/projects/valtimo/process-management/src/lib/components/process-management-editor/process-management-editor.component.html +++ /dev/null @@ -1,116 +0,0 @@ - - -
-
- -
- -
-
- -
-
- -
-
- -
-
-
- - - - - -
-
-
- - - -
- -
- {{ - 'processManagement.readOnly' | translate - }} - - {{ - 'processManagement.systemProcess' | translate - }} -
-
- -
- - {{ 'interface.export' | translate }} - - - -
-
-
-
diff --git a/projects/valtimo/process-management/src/lib/components/process-management-editor/process-management-editor.component.scss b/projects/valtimo/process-management/src/lib/components/process-management-editor/process-management-editor.component.scss deleted file mode 100644 index 22530d361..000000000 --- a/projects/valtimo/process-management/src/lib/components/process-management-editor/process-management-editor.component.scss +++ /dev/null @@ -1,100 +0,0 @@ -/*! - * Copyright 2015-2024 Ritense BV, the Netherlands. - * - * Licensed under EUPL, Version 1.2 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -.bpmn { - &__container { - position: relative; - background-color: var(--cds-layer); - width: 100%; - } - - &__modeler { - width: 100%; - height: 100%; - flex-direction: row; - padding: 1px; - box-sizing: border-box; - outline: 1px solid var(--cds-border-subtle); - outline-offset: -1px; - - // hide blue focus border bpmn - ::ng-deep .djs-container > svg { - outline: none !important; - } - } - - &__modeler-canvas { - width: 100%; - } - - &__modeler-panel { - width: 481px; - padding-left: 1px; - box-shadow: inset 1px 0 0 0 var(--cds-border-subtle); - box-sizing: border-box; - } - - &__loading { - width: 100%; - height: 100%; - display: flex; - justify-content: center; - align-items: center; - background-color: var(--cds-background-selected); - } -} - -.page-header-actions { - display: flex; - width: 100%; - justify-content: space-between; - - &__left-container { - display: flex; - gap: 24px; - align-items: flex-end; - } - - &__tags { - display: flex; - gap: 8px; - align-items: flex-end; - } - - &__version-dropdown { - width: 150px; - } - - &__buttons { - display: flex; - gap: 16px; - } -} - -::ng-deep .process-link-properties-panel { - padding: 8px 12px 16px 12px; - width: 100%; - display: flex; - flex-direction: row; - gap: 16px; - - .cds--btn { - flex-shrink: 1; - width: 100%; - display: flex; - align-items: center; - } -} diff --git a/projects/valtimo/process-management/src/lib/components/process-management-editor/process-management-editor.component.ts b/projects/valtimo/process-management/src/lib/components/process-management-editor/process-management-editor.component.ts deleted file mode 100644 index 6a0f81b71..000000000 --- a/projects/valtimo/process-management/src/lib/components/process-management-editor/process-management-editor.component.ts +++ /dev/null @@ -1,482 +0,0 @@ -/* - * Copyright 2015-2024 Ritense BV, the Netherlands. - * - * Licensed under EUPL, Version 1.2 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import {AfterViewInit, Component, ElementRef, OnDestroy, ViewChild} from '@angular/core'; -import {CommonModule} from '@angular/common'; -import { - CARBON_CONSTANTS, - FitPageDirectiveModule, - ModalService, - PageHeaderService, - PageTitleService, - RenderInPageHeaderDirectiveModule, -} from '@valtimo/components'; -import {ActivatedRoute, Router} from '@angular/router'; -import { - BehaviorSubject, - combineLatest, - filter, - from, - map, - Observable, - startWith, - Subject, - Subscription, - switchMap, - take, - tap, -} from 'rxjs'; -import {ProcessDefinition, ProcessService} from '@valtimo/process'; -import { - ButtonModule, - DialogModule, - DropdownModule, - IconModule, - IconService, - ListItem, - LoadingModule, - NotificationModule, - NotificationService, - SelectModule, - TagModule, -} from 'carbon-components-angular'; -import Modeler from 'bpmn-js/lib/Modeler'; -import NavigatedViewer from 'bpmn-js/lib/NavigatedViewer'; -import {ReactiveFormsModule} from '@angular/forms'; -import {TranslateModule, TranslateService} from '@ngx-translate/core'; -import {Deploy16, Download16} from '@carbon/icons'; -import { - BpmnPropertiesPanelModule, - BpmnPropertiesProviderModule, - CamundaPlatformPropertiesProviderModule, -} from 'bpmn-js-properties-panel'; -import camundaPlatformBehaviors from 'camunda-bpmn-js-behaviors/lib/camunda-platform'; -import CamundaBpmnModdle from 'camunda-bpmn-moddle/resources/camunda.json'; -import {ValtimoPropertiesProviderModule} from './panel'; -import {distinctUntilChanged} from 'rxjs/operators'; -import {isEqual} from 'lodash'; -import {ProcessManagementEditorService} from '../../services'; -import {OpenProcessLinkModalEvent, ProcessManagementWindow} from '../../models'; -import { - ProcessLinkButtonService, - ProcessLinkCreateEvent, - ProcessLinkEditMode, - ProcessLinkModule, - ProcessLinkService, - ProcessLinkStateService, - ProcessLinkStepService, -} from '@valtimo/process-link'; -import {EMPTY_BPMN} from '../../constants'; - -@Component({ - selector: 'valtimo-process-management-editor', - templateUrl: './process-management-editor.component.html', - styleUrls: ['./process-management-editor.component.scss'], - standalone: true, - imports: [ - CommonModule, - FitPageDirectiveModule, - LoadingModule, - RenderInPageHeaderDirectiveModule, - DropdownModule, - ReactiveFormsModule, - SelectModule, - ButtonModule, - IconModule, - TranslateModule, - TagModule, - ProcessLinkModule, - ProcessLinkModule, - DialogModule, - NotificationModule, - ], - providers: [ - ProcessManagementEditorService, - ProcessLinkStateService, - ProcessLinkStepService, - ProcessLinkButtonService, - NotificationService, - ], -}) -export class ProcessManagementEditorComponent implements AfterViewInit, OnDestroy { - @ViewChild('modeler', {static: false}) modelerElementRef!: ElementRef; - @ViewChild('modelerPanel', {static: false}) modelerPanelElementRef!: ElementRef; - @ViewChild('viewer', {static: false}) viewerElementRef!: ElementRef; - @ViewChild('viewerPanel', {static: false}) viewerPanelElementRef!: ElementRef; - - public readonly loading$ = new BehaviorSubject(true); - - private _bpmnModeler!: Modeler; - private _bpmnViewer!: NavigatedViewer; - - public isReadOnlyProcess$ = new BehaviorSubject(false); - public isSystemProcess$ = new BehaviorSubject(false); - - public readonly selectedProcessDefinitionXml$ = - this.processManagementEditorService.selectionProcessDefinition$.pipe( - filter(selectedProcessDefinition => !!selectedProcessDefinition?.id), - distinctUntilChanged((previous, current) => isEqual(previous, current)), - tap(selectedProcessDefinition => { - this.loading$.next(true); - this.pageTitleService.setCustomPageTitle(selectedProcessDefinition.name); - }), - switchMap(selectedProcessDefinition => - this.processService.getProcessDefinitionXml(selectedProcessDefinition.id) - ), - tap(result => { - this._bpmnModeler?.importXML(result.bpmn20Xml); - this._bpmnViewer?.importXML(result.bpmn20Xml); - this.isReadOnlyProcess$.next(result.readOnly); - this.isSystemProcess$.next(result.systemProcess); - this.loading$.next(false); - }) - ); - - private readonly _processDefinitionKey$ = this.route.params.pipe( - map(params => params.key), - filter(key => !!key) - ); - - private readonly _reload$ = new Subject(); - - public readonly changesPending$ = new BehaviorSubject(false); - - public readonly processDefinitionVersions$ = combineLatest([ - this._processDefinitionKey$, - this._reload$.pipe(startWith(null)), - ]).pipe( - switchMap(([processDefinitionKey]) => - this.processService.getProcessDefinitionVersions(processDefinitionKey) - ), - tap(processDefinitions => { - this.changesPending$.next(false); - this.setSelectedProcessDefinitionToLatest(processDefinitions); - }) - ); - - public readonly processDefinitionVersionsListItems$: Observable = combineLatest([ - this.processDefinitionVersions$, - this.processManagementEditorService.selectionProcessDefinition$, - this.translateService.stream('key'), - ]).pipe( - map(([processDefinitionVersions, selectionProcessDefinition]) => - processDefinitionVersions - .map(processDefinitionVersion => ({ - id: processDefinitionVersion.version, - content: `${this.translateService.instant('processManagement.version')}${processDefinitionVersion.version}`, - selected: selectionProcessDefinition.version === processDefinitionVersion.version, - processDefinitionVersion, - })) - .sort((a, b) => b.id - a.id) - ) - ); - - public readonly compactMode$ = this.pageHeaderService.compactMode$; - - public readonly creatingNewProcess$ = new BehaviorSubject(false); - - private readonly _subscriptions = new Subscription(); - - constructor( - private readonly route: ActivatedRoute, - private readonly processService: ProcessService, - private readonly pageTitleService: PageTitleService, - private readonly translateService: TranslateService, - private readonly iconService: IconService, - private readonly pageHeaderService: PageHeaderService, - private readonly processManagementEditorService: ProcessManagementEditorService, - private readonly modalService: ModalService, - private readonly processLinkService: ProcessLinkService, - private readonly processLinkStateService: ProcessLinkStateService, - private readonly router: Router, - private readonly notificationService: NotificationService - ) { - this.iconService.registerAll([Deploy16, Download16]); - (window as any as ProcessManagementWindow).processManagementEditorService = - processManagementEditorService; - (window as any as ProcessManagementWindow).translateService = translateService; - } - - public ngAfterViewInit(): void { - this.initModeler(); - this.initViewer(); - this.subscribeToOpenProcessLinkModalEvents(); - this.subscribeToProcessLinkUpdateEvents(); - this.subscribeToProcessLinkCreateEvents(); - this.subscribeToProcessLinkDeleteEvents(); - this.processLinkStateService.setEditMode(ProcessLinkEditMode.EMIT_EVENTS); - this.initIfCreate(); - } - - public ngOnDestroy(): void { - this._bpmnModeler?.destroy(); - this._bpmnViewer?.destroy(); - this._subscriptions.unsubscribe(); - } - - public deployChanges(isReadOnlyProcess: boolean): void { - combineLatest([ - isReadOnlyProcess ? from(this._bpmnViewer.saveXML()) : from(this._bpmnModeler.saveXML()), - this.processManagementEditorService.processLinksForSelectedDefinition$, - this.processManagementEditorService.selectionProcessDefinition$, - ]) - .pipe( - take(1), - switchMap(([result, processLinks, selectedProcessDefinition]) => - this.processLinkService.deployProcessWithProcessLinks( - processLinks as ProcessLinkCreateEvent[], - selectedProcessDefinition.id, - !isReadOnlyProcess ? result.xml : null - ) - ) - ) - .subscribe(() => { - this.reload(); - }); - } - - public deployNewProcessDefinition(): void { - combineLatest([ - from(this._bpmnModeler.saveXML()), - this.processManagementEditorService.processLinksForSelectedDefinition$, - ]) - .pipe( - take(1), - switchMap(([result, processLinks]) => - this.processLinkService.deployProcessWithProcessLinks( - processLinks.map(link => ({ - ...link, - processDefinitionId: '-', - })) as ProcessLinkCreateEvent[], - null, - result.xml - ) - ) - ) - .subscribe(() => { - this.router.navigate(['/processes']); - this.notificationService.showToast({ - caption: this.translateService.instant('formFlow.savedSuccessTitleMessage'), - type: 'success', - duration: CARBON_CONSTANTS.notificationDuration, - showClose: true, - title: this.translateService.instant('formFlow.savedSuccessTitle'), - }); - }); - } - - public export(isReadOnlyProcess: boolean): void { - (isReadOnlyProcess ? from(this._bpmnViewer.saveXML()) : from(this._bpmnModeler.saveXML())) - .pipe(take(1)) - .subscribe(result => { - const file = new Blob([result.xml], {type: 'text/xml'}); - const link = document.createElement('a'); - link.download = 'diagram.bpmn'; - link.href = window.URL.createObjectURL(file); - link.click(); - window.URL.revokeObjectURL(link.href); - link.remove(); - }); - } - - public selectedVersionChange(event: {item: {processDefinitionVersion: ProcessDefinition}}): void { - this.processManagementEditorService.selectionProcessDefinition$ - .pipe(take(1)) - .subscribe(selectedVersion => { - if (selectedVersion.id !== event.item.processDefinitionVersion.id) { - this.processManagementEditorService.setSelectedProcessDefinition( - event?.item?.processDefinitionVersion - ); - this.changesPending$.next(false); - } - }); - } - - private setSelectedProcessDefinitionToLatest(processDefinitions: ProcessDefinition[]): void { - this.processManagementEditorService.setSelectedProcessDefinition( - processDefinitions.reduce((acc, version) => (version.version > acc.version ? version : acc)) - ); - } - - private initModeler(): void { - this._bpmnModeler = new Modeler({ - additionalModules: [ - BpmnPropertiesPanelModule, - BpmnPropertiesProviderModule, - CamundaPlatformPropertiesProviderModule, - camundaPlatformBehaviors, - ValtimoPropertiesProviderModule, - ], - moddleExtensions: { - camunda: CamundaBpmnModdle, - }, - propertiesPanel: { - parent: this.modelerPanelElementRef.nativeElement, - }, - }); - - this._bpmnModeler?.attachTo(this.modelerElementRef.nativeElement); - - this._bpmnModeler.on('commandStack.changed', () => { - this.changesPending$.next(true); - }); - } - - private initViewer(): void { - const disableCommands = () => { - const commandStack = this._bpmnViewer.get('commandStack') as any; - const originalExecute = commandStack?.execute?.bind(commandStack); - - if (commandStack?.execute) { - commandStack.execute = (command: string, context: any) => { - if ( - command === 'elements.delete' || - command === 'elements.copy' || - command === 'elements.paste' || - command === 'elements.create' - ) { - return; - } - originalExecute(command, context); - }; - } - }; - - const DisableBpmnWriteModule = { - paletteProvider: ['value', {}], - contextPadProvider: ['value', {}], - directEditing: [ - 'value', - { - registerProvider: () => {}, - activate: () => {}, - deactivate: () => {}, - isActive: () => false, - }, - ], - move: ['value', null], - resizeHandles: [ - 'value', - { - addResizer: () => {}, - removeResizers: () => {}, - }, - ], - }; - - this._bpmnViewer = new Modeler({ - additionalModules: [ - DisableBpmnWriteModule, - BpmnPropertiesPanelModule, - ValtimoPropertiesProviderModule, - ], - moddleExtensions: { - camunda: CamundaBpmnModdle, - }, - propertiesPanel: { - parent: this.viewerPanelElementRef.nativeElement, - }, - }); - - this._bpmnViewer?.attachTo(this.viewerElementRef.nativeElement); - - this._bpmnViewer.on('import.done', () => { - disableCommands(); - }); - - this._bpmnViewer.on('commandStack.changed', () => { - this.changesPending$.next(true); - }); - } - - private reload(): void { - this._reload$.next(null); - } - - private handleUpdateEvent(event: OpenProcessLinkModalEvent): void { - this.modalService.setModalData(event?.modalParams); - this.processLinkStateService.setModalParams(event?.modalParams); - this.processLinkStateService.setElementName(event?.modalParams?.element?.name); - this.processLinkStateService.selectProcessLink(event.processLink); - this.processLinkStateService.showModal(); - } - - private handleCreateEvent(event: OpenProcessLinkModalEvent): void { - this.processLinkService - .getProcessLinkCandidates(event.modalParams.element.activityListenerType) - .subscribe(candidates => { - this.modalService.setModalData(event?.modalParams); - this.processLinkStateService.setModalParams(event?.modalParams); - this.processLinkStateService.setElementName(event?.modalParams?.element?.name); - this.processLinkStateService.setAvailableProcessLinkTypes(candidates); - this.processLinkStateService.showModal(); - }); - } - - private subscribeToOpenProcessLinkModalEvents(): void { - this._subscriptions.add( - this.processManagementEditorService.openProcessLinkModalEvents$.subscribe(event => { - if (event.processLink) { - this.handleUpdateEvent(event); - } else { - this.handleCreateEvent(event); - } - }) - ); - } - - private subscribeToProcessLinkUpdateEvents(): void { - this._subscriptions.add( - this.processLinkStateService.processLinkUpdateEvents$.subscribe(event => { - this.processManagementEditorService.updateProcessLink(event); - this.processLinkStateService.stopSaving(); - this.processLinkStateService.closeModal(); - }) - ); - } - - private subscribeToProcessLinkCreateEvents(): void { - this._subscriptions.add( - this.processLinkStateService.processLinkCreateEvents$.subscribe(event => { - this.processManagementEditorService.createProcessLink(event); - this.processLinkStateService.stopSaving(); - this.processLinkStateService.closeModal(); - }) - ); - } - - private subscribeToProcessLinkDeleteEvents(): void { - this._subscriptions.add( - this.processLinkStateService.processLinkDeleteEvents$.subscribe(event => { - this.processManagementEditorService.deleteProcessLink(event); - this.processLinkStateService.stopSaving(); - this.processLinkStateService.closeModal(); - }) - ); - } - - private initIfCreate(): void { - const currentUrl = this.route.snapshot.url.toString(); - - if (!currentUrl.includes('create')) return; - - this.creatingNewProcess$.next(true); - this._bpmnModeler?.importXML(EMPTY_BPMN); - this.isReadOnlyProcess$.next(false); - this.isSystemProcess$.next(false); - this.loading$.next(false); - } -} diff --git a/projects/valtimo/process-management/src/lib/process-management-routing.ts b/projects/valtimo/process-management/src/lib/process-management-routing.ts index 343855b1e..284e0e413 100644 --- a/projects/valtimo/process-management/src/lib/process-management-routing.ts +++ b/projects/valtimo/process-management/src/lib/process-management-routing.ts @@ -18,9 +18,8 @@ import {NgModule} from '@angular/core'; import {RouterModule, Routes} from '@angular/router'; import {CommonModule} from '@angular/common'; import {AuthGuardService} from '@valtimo/security'; -import {ProcessManagementComponent} from './components/process-management/process-management.component'; import {ROLE_ADMIN} from '@valtimo/config'; -import {ProcessManagementEditorComponent} from './components/process-management-editor/process-management-editor.component'; +import {ProcessManagementBuilderComponent, ProcessManagementComponent} from './components'; const routes: Routes = [ { @@ -31,13 +30,13 @@ const routes: Routes = [ }, { path: 'processes/create', - component: ProcessManagementEditorComponent, + component: ProcessManagementBuilderComponent, canActivate: [AuthGuardService], data: {title: 'Create new Process', roles: [ROLE_ADMIN]}, }, { path: 'processes/process/:key', - component: ProcessManagementEditorComponent, + component: ProcessManagementBuilderComponent, canActivate: [AuthGuardService], data: {title: 'Process details', roles: [ROLE_ADMIN], customPageTitle: true}, }, diff --git a/projects/valtimo/process-management/src/lib/process-management.module.ts b/projects/valtimo/process-management/src/lib/process-management.module.ts index c817e9e8c..2c62b7b13 100644 --- a/projects/valtimo/process-management/src/lib/process-management.module.ts +++ b/projects/valtimo/process-management/src/lib/process-management.module.ts @@ -24,7 +24,6 @@ import {ProcessLinkModule} from '@valtimo/process-link'; import { ProcessManagementBuilderComponent, ProcessManagementComponent, - ProcessManagementEditorComponent, ProcessManagementListComponent, ProcessManagementUploadComponent, } from './components'; @@ -40,7 +39,6 @@ import { @NgModule({ declarations: [ ProcessManagementComponent, - ProcessManagementBuilderComponent, ProcessManagementListComponent, ProcessManagementUploadComponent, ], @@ -52,7 +50,7 @@ import { FormsModule, TranslateModule, ProcessLinkModule, - ProcessManagementEditorComponent, + ProcessManagementBuilderComponent, CarbonListModule, ButtonModule, IconModule,