@valtimo/process-management 13.34.0 → 13.36.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/valtimo-process-management.mjs +399 -27
- package/fesm2022/valtimo-process-management.mjs.map +1 -1
- package/lib/components/process-management-builder/panel/valtimo-properties-provider.d.ts.map +1 -1
- package/lib/components/process-management-builder/process-management-builder.component.d.ts +29 -4
- package/lib/components/process-management-builder/process-management-builder.component.d.ts.map +1 -1
- package/lib/components/process-management-list/process-management-list.component.d.ts +11 -1
- package/lib/components/process-management-list/process-management-list.component.d.ts.map +1 -1
- package/lib/constants/process-management.test-ids.d.ts +1 -0
- package/lib/constants/process-management.test-ids.d.ts.map +1 -1
- package/lib/models/process-management.model.d.ts +19 -1
- package/lib/models/process-management.model.d.ts.map +1 -1
- package/lib/models/process.model.d.ts +1 -0
- package/lib/models/process.model.d.ts.map +1 -1
- package/lib/services/process-management-editor.service.d.ts +5 -1
- package/lib/services/process-management-editor.service.d.ts.map +1 -1
- package/lib/services/process-management.service.d.ts +2 -1
- package/lib/services/process-management.service.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
import * as i6 from '@angular/common';
|
|
2
2
|
import { CommonModule } from '@angular/common';
|
|
3
3
|
import * as i0 from '@angular/core';
|
|
4
|
-
import { Injectable, signal,
|
|
4
|
+
import { Injectable, signal, ViewChild, Component, EventEmitter, Output, ChangeDetectionStrategy, NgModule } from '@angular/core';
|
|
5
5
|
import * as i1$2 from '@angular/forms';
|
|
6
6
|
import { ReactiveFormsModule, Validators, FormsModule } from '@angular/forms';
|
|
7
7
|
import * as i9 from '@ngx-translate/core';
|
|
8
8
|
import { TranslateModule, TranslateService } from '@ngx-translate/core';
|
|
9
9
|
import * as i1$1 from '@valtimo/components';
|
|
10
|
-
import { FitPageDirective, RenderInPageHeaderDirective, OverflowMenuComponent, OverflowMenuOptionComponent, OverflowMenuTriggerComponent, ViewType, CarbonListModule,
|
|
10
|
+
import { FitPageDirective, RenderInPageHeaderDirective, OverflowMenuComponent, OverflowMenuOptionComponent, OverflowMenuTriggerComponent, ConfirmationModalModule, ViewType, CarbonListModule, CARBON_CONSTANTS, RenderInBodyComponent, WidgetModule } from '@valtimo/components';
|
|
11
11
|
import * as i5 from '@valtimo/process-link';
|
|
12
12
|
import { ProcessLinkModule, ProcessLinkStateService, ProcessLinkStepService, ProcessLinkButtonService } from '@valtimo/process-link';
|
|
13
13
|
import * as i2$2 from 'carbon-components-angular';
|
|
14
14
|
import { LoadingModule, DropdownModule, SelectModule, ButtonModule, IconModule, TagModule, ToggleModule, TooltipModule, FileUploaderModule, ModalModule, LayerModule, NotificationModule, RadioModule } from 'carbon-components-angular';
|
|
15
15
|
import * as i1 from '@angular/common/http';
|
|
16
16
|
import { HttpErrorResponse } from '@angular/common/http';
|
|
17
|
+
import { Deploy16, ListChecked16, Return16, Upload16 } from '@carbon/icons';
|
|
17
18
|
import * as i2$1 from '@valtimo/shared';
|
|
18
19
|
import { BaseApiService, getCaseManagementRouteParams, getBuildingBlockManagementRouteParams, ROLE_ADMIN } from '@valtimo/shared';
|
|
19
20
|
import { useService, BpmnPropertiesPanelModule, BpmnPropertiesProviderModule, CamundaPlatformPropertiesProviderModule } from 'bpmn-js-properties-panel';
|
|
@@ -32,7 +33,6 @@ import * as i7 from '@valtimo/process';
|
|
|
32
33
|
import * as i8 from '@angular/router';
|
|
33
34
|
import { RouterModule } from '@angular/router';
|
|
34
35
|
import * as i10 from '@valtimo/plugin';
|
|
35
|
-
import { Upload16 } from '@carbon/icons';
|
|
36
36
|
import { AuthGuardService } from '@valtimo/security';
|
|
37
37
|
|
|
38
38
|
/*
|
|
@@ -86,6 +86,7 @@ const PROCESS_MANAGEMENT_LIST_TEST_IDS = {
|
|
|
86
86
|
createProcessButton: 'processManagementCreateProcessButton',
|
|
87
87
|
};
|
|
88
88
|
const PROCESS_MANAGEMENT_BUILDER_TEST_IDS = {
|
|
89
|
+
draftToggle: 'processManagementBuilderDraftToggle',
|
|
89
90
|
startsCaseToggle: 'processManagementBuilderStartsCaseToggle',
|
|
90
91
|
startableByUserToggle: 'processManagementBuilderStartableByUserToggle',
|
|
91
92
|
deployButton: 'processManagementBuilderDeployButton',
|
|
@@ -147,6 +148,12 @@ class ProcessManagementEditorService {
|
|
|
147
148
|
get formDefinitionOptions() {
|
|
148
149
|
return this._formDefinitionOptions$.getValue();
|
|
149
150
|
}
|
|
151
|
+
get validationErrors() {
|
|
152
|
+
return this._validationErrors$.getValue();
|
|
153
|
+
}
|
|
154
|
+
setValidationErrors(errors) {
|
|
155
|
+
this._validationErrors$.next(errors);
|
|
156
|
+
}
|
|
150
157
|
constructor(processLinkService, formService) {
|
|
151
158
|
this.processLinkService = processLinkService;
|
|
152
159
|
this.formService = formService;
|
|
@@ -156,6 +163,8 @@ class ProcessManagementEditorService {
|
|
|
156
163
|
this._deleteProcessLinkEvents$ = new Subject();
|
|
157
164
|
this._managementRouteParams$ = new BehaviorSubject(null);
|
|
158
165
|
this._formDefinitionOptions$ = new BehaviorSubject([]);
|
|
166
|
+
this._validationErrors$ = new BehaviorSubject([]);
|
|
167
|
+
this.validationErrors$ = this._validationErrors$.asObservable();
|
|
159
168
|
this._updatingBpmnView = false;
|
|
160
169
|
this._activityIdBusinessIdMap = {};
|
|
161
170
|
this._subscriptions = new Subscription();
|
|
@@ -466,6 +475,9 @@ class ProcessManagementService extends BaseApiService {
|
|
|
466
475
|
updateProcessDefinitionCaseDefinitionProperties(caseDefinitionKey, caseDefinitionVersionTag, processDefinitionId, body) {
|
|
467
476
|
return this.httpClient.put(this.getApiUrl(`/management/v1/case-definition/${caseDefinitionKey}/version/${caseDefinitionVersionTag}/process/${processDefinitionId}/properties`), body);
|
|
468
477
|
}
|
|
478
|
+
validateProcessDefinition(request) {
|
|
479
|
+
return this.httpClient.post(this.getApiUrl('/management/v1/process-definition/validate'), request);
|
|
480
|
+
}
|
|
469
481
|
getProcesses(definitionName, versionTag) {
|
|
470
482
|
return this.httpClient.get(this.getApiUrl(`${PROCESS_MANAGEMENT_ENDPOINTS[this._$context()]}/${definitionName}/version/${versionTag}/process-definition`));
|
|
471
483
|
}
|
|
@@ -761,7 +773,28 @@ class ValtimoPropertiesProvider {
|
|
|
761
773
|
}
|
|
762
774
|
getGroups(element) {
|
|
763
775
|
const processLink = this.processManagementEditorService.processLinksForSelectedDefinition.find(processLink => processLink.activityId === element.id) || null;
|
|
776
|
+
const elementErrors = this.processManagementEditorService.validationErrors.filter(error => error.elementId === element.id);
|
|
764
777
|
return (groups) => {
|
|
778
|
+
const generalGroup = groups.find((g) => g.id === 'general');
|
|
779
|
+
if (generalGroup) {
|
|
780
|
+
generalGroup.entries = generalGroup.entries.filter((entry) => entry.id !== 'isExecutable');
|
|
781
|
+
}
|
|
782
|
+
if (elementErrors.length > 0) {
|
|
783
|
+
const errorGroup = {
|
|
784
|
+
id: 'validationErrorsGroup',
|
|
785
|
+
label: this.translateService.instant('processManagement.validationErrors'),
|
|
786
|
+
entries: [
|
|
787
|
+
{
|
|
788
|
+
id: 'validationErrorsEntry',
|
|
789
|
+
errors: elementErrors,
|
|
790
|
+
translateService: this.translateService,
|
|
791
|
+
component: ValidationErrorsElement,
|
|
792
|
+
},
|
|
793
|
+
],
|
|
794
|
+
shouldOpen: true,
|
|
795
|
+
};
|
|
796
|
+
groups.unshift(errorGroup);
|
|
797
|
+
}
|
|
765
798
|
if (is(element, 'bpmn:UserTask') ||
|
|
766
799
|
is(element, 'bpmn:StartEvent') ||
|
|
767
800
|
is(element, 'bpmn:ServiceTask') ||
|
|
@@ -1035,6 +1068,24 @@ const CustomRootElement = (props) => {
|
|
|
1035
1068
|
</div>`;
|
|
1036
1069
|
return processLink ? genericLinkedPanel : genericCreatePanel;
|
|
1037
1070
|
};
|
|
1071
|
+
const ValidationErrorsElement = (props) => {
|
|
1072
|
+
const getErrorMessage = (error) => {
|
|
1073
|
+
if (error.errorCode) {
|
|
1074
|
+
const translationKey = `processManagement.expressionErrors.${error.errorCode}`;
|
|
1075
|
+
const translated = props.translateService.instant(translationKey);
|
|
1076
|
+
if (translated !== translationKey) {
|
|
1077
|
+
return error.expression ? `${translated}: '${error.expression}'` : translated;
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
return error.reason;
|
|
1081
|
+
};
|
|
1082
|
+
return html `<div class="validation-errors-panel">
|
|
1083
|
+
${props.errors.map(error => html `<div class="validation-errors-panel__item${error.severity === 'WARNING' ? ' warning' : ''}">
|
|
1084
|
+
<span class="validation-errors-panel__icon${error.severity === 'WARNING' ? ' warning' : ''}">!</span>
|
|
1085
|
+
<span class="validation-errors-panel__reason${error.severity === 'WARNING' ? ' warning' : ''}">${getErrorMessage(error)}</span>
|
|
1086
|
+
</div>`)}
|
|
1087
|
+
</div>`;
|
|
1088
|
+
};
|
|
1038
1089
|
const ValtimoPropertiesProviderModule = {
|
|
1039
1090
|
__init__: ['customPropertiesProvider'],
|
|
1040
1091
|
customPropertiesProvider: ['type', ValtimoPropertiesProvider],
|
|
@@ -1057,7 +1108,7 @@ const ValtimoPropertiesProviderModule = {
|
|
|
1057
1108
|
*/
|
|
1058
1109
|
|
|
1059
1110
|
/*
|
|
1060
|
-
* Copyright 2015-
|
|
1111
|
+
* Copyright 2015-2026 Ritense BV, the Netherlands.
|
|
1061
1112
|
*
|
|
1062
1113
|
* Licensed under EUPL, Version 1.2 (the "License");
|
|
1063
1114
|
* you may not use this file except in compliance with the License.
|
|
@@ -1093,10 +1144,15 @@ class ProcessManagementBuilderComponent {
|
|
|
1093
1144
|
this.processLinkBuildingBlockApiService = processLinkBuildingBlockApiService;
|
|
1094
1145
|
this._selectedProcess$ = new BehaviorSubject(null);
|
|
1095
1146
|
this.loading$ = new BehaviorSubject(true);
|
|
1147
|
+
this._validationErrorElementIds = [];
|
|
1148
|
+
this._validationHoverHandler = null;
|
|
1149
|
+
this._validationOutHandler = null;
|
|
1096
1150
|
this.isReadOnlyProcess$ = new BehaviorSubject(false);
|
|
1097
1151
|
this.isSystemProcess$ = new BehaviorSubject(false);
|
|
1152
|
+
this.draft$ = new BehaviorSubject(false);
|
|
1098
1153
|
this.canInitializeDocument$ = new BehaviorSubject(false);
|
|
1099
1154
|
this.startableByUser$ = new BehaviorSubject(false);
|
|
1155
|
+
this.validationErrors$ = this.processManagementEditorService.validationErrors$;
|
|
1100
1156
|
this.testIds = PROCESS_MANAGEMENT_BUILDER_TEST_IDS;
|
|
1101
1157
|
this.selectedProcessDefinitionXml$ = this.processManagementEditorService.selectionProcessDefinition$.pipe(filter(selectedProcessDefinition => !!selectedProcessDefinition?.id), distinctUntilChanged((previous, current) => isEqual(previous, current)), tap(selectedProcessDefinition => {
|
|
1102
1158
|
this.loading$.next(true);
|
|
@@ -1105,6 +1161,7 @@ class ProcessManagementBuilderComponent {
|
|
|
1105
1161
|
this.cleanUpListenersOnModeler();
|
|
1106
1162
|
this._bpmnModeler?.importXML(result.bpmn20Xml);
|
|
1107
1163
|
this._bpmnViewer?.importXML(result.bpmn20Xml);
|
|
1164
|
+
this.draft$.next(this.parseDraftFromXml(result.bpmn20Xml));
|
|
1108
1165
|
this.isReadOnlyProcess$.next(result.readOnly);
|
|
1109
1166
|
this.isSystemProcess$.next(result.systemProcess);
|
|
1110
1167
|
this.loading$.next(false);
|
|
@@ -1150,8 +1207,9 @@ class ProcessManagementBuilderComponent {
|
|
|
1150
1207
|
.sort((a, b) => b.id - a.id)));
|
|
1151
1208
|
this.compactMode$ = this.pageHeaderService.compactMode$;
|
|
1152
1209
|
this.creatingNewProcess$ = new BehaviorSubject(false);
|
|
1153
|
-
this.$spaceAdjustment = computed(() => this.processManagementService.$context() === 'case' ? 0 : 0);
|
|
1154
1210
|
this.updatingProcessDefinitionCaseDefinition$ = new BehaviorSubject(false);
|
|
1211
|
+
this.showWarningConfirmationModal$ = new BehaviorSubject(false);
|
|
1212
|
+
this._pendingDeployAction = null;
|
|
1155
1213
|
this._subscriptions = new Subscription();
|
|
1156
1214
|
this.shapeAddedHandler = (event) => {
|
|
1157
1215
|
this.logger.debug('Shape added:', event);
|
|
@@ -1171,10 +1229,12 @@ class ProcessManagementBuilderComponent {
|
|
|
1171
1229
|
return;
|
|
1172
1230
|
this.processManagementEditorService.updateProcessLinksOnIdChange(activityId, businessId);
|
|
1173
1231
|
};
|
|
1232
|
+
this.iconService.registerAll([Deploy16, ListChecked16, Return16]);
|
|
1174
1233
|
this.setProcessManagementWindow();
|
|
1175
1234
|
}
|
|
1176
1235
|
ngAfterViewInit() {
|
|
1177
1236
|
this.pageTitleService.disableReset();
|
|
1237
|
+
this.pageHeaderService.enableTitleAsBreadcrumb();
|
|
1178
1238
|
this.openParamsAndContextSubscription();
|
|
1179
1239
|
this.initModeler();
|
|
1180
1240
|
this.initViewer();
|
|
@@ -1185,10 +1245,12 @@ class ProcessManagementBuilderComponent {
|
|
|
1185
1245
|
this.initEditing();
|
|
1186
1246
|
}
|
|
1187
1247
|
ngOnDestroy() {
|
|
1248
|
+
this.clearValidationErrors();
|
|
1188
1249
|
this._bpmnModeler?.destroy();
|
|
1189
1250
|
this._bpmnViewer?.destroy();
|
|
1190
1251
|
this._subscriptions.unsubscribe();
|
|
1191
1252
|
this.pageTitleService.enableReset();
|
|
1253
|
+
this.pageHeaderService.disableTitleAsBreadcrumb();
|
|
1192
1254
|
this.pageTitleService.clearPageActionsViewContainerRef();
|
|
1193
1255
|
this.breadcrumbService.clearThirdBreadcrumb();
|
|
1194
1256
|
this.breadcrumbService.clearFourthBreadcrumb();
|
|
@@ -1206,7 +1268,37 @@ class ProcessManagementBuilderComponent {
|
|
|
1206
1268
|
link.remove();
|
|
1207
1269
|
});
|
|
1208
1270
|
}
|
|
1271
|
+
validateProcessDefinition(isReadOnlyProcess) {
|
|
1272
|
+
combineLatest([
|
|
1273
|
+
from(isReadOnlyProcess ? this._bpmnViewer.saveXML() : this._bpmnModeler.saveXML()),
|
|
1274
|
+
this.processManagementEditorService.processLinksForSelectedDefinition$,
|
|
1275
|
+
])
|
|
1276
|
+
.pipe(take(1), switchMap(([result, processLinks]) => {
|
|
1277
|
+
const xml = this.applyDraftState(result?.xml ?? '') ?? '';
|
|
1278
|
+
return this.processManagementService.validateProcessDefinition({
|
|
1279
|
+
bpmnXml: xml,
|
|
1280
|
+
processLinks: processLinks.map(link => ({
|
|
1281
|
+
...link,
|
|
1282
|
+
processDefinitionId: '-',
|
|
1283
|
+
})),
|
|
1284
|
+
});
|
|
1285
|
+
}))
|
|
1286
|
+
.subscribe({
|
|
1287
|
+
next: validationResult => {
|
|
1288
|
+
this.highlightValidationErrors(validationResult.errors);
|
|
1289
|
+
if (validationResult.isValid && !validationResult.hasWarnings) {
|
|
1290
|
+
this.showNotification('validationSuccess');
|
|
1291
|
+
}
|
|
1292
|
+
},
|
|
1293
|
+
error: () => {
|
|
1294
|
+
this.showNotification('error');
|
|
1295
|
+
},
|
|
1296
|
+
});
|
|
1297
|
+
}
|
|
1209
1298
|
deployChanges(isReadOnlyProcess) {
|
|
1299
|
+
this.validateAndDeploy(isReadOnlyProcess, () => this.executeDeployChanges(isReadOnlyProcess));
|
|
1300
|
+
}
|
|
1301
|
+
executeDeployChanges(isReadOnlyProcess) {
|
|
1210
1302
|
combineLatest([
|
|
1211
1303
|
from(isReadOnlyProcess ? this._bpmnViewer.saveXML() : this._bpmnModeler.saveXML()),
|
|
1212
1304
|
this.processManagementEditorService.processLinksForSelectedDefinition$,
|
|
@@ -1215,18 +1307,20 @@ class ProcessManagementBuilderComponent {
|
|
|
1215
1307
|
this.managementParams$.pipe(startWith(null)),
|
|
1216
1308
|
])
|
|
1217
1309
|
.pipe(take(1), switchMap(([result, processLinks, selectedProcessDefinition, context, params]) => {
|
|
1310
|
+
const xml = !isReadOnlyProcess ? this.applyDraftState(result?.xml ?? '') : null;
|
|
1218
1311
|
if (context === 'case') {
|
|
1219
1312
|
const caseManagementParams = params;
|
|
1220
|
-
return this.processLinkService.updateProcessDefinitionForCase(processLinks, selectedProcessDefinition.id,
|
|
1313
|
+
return this.processLinkService.updateProcessDefinitionForCase(processLinks, selectedProcessDefinition.id, xml, caseManagementParams?.caseDefinitionKey ?? '', caseManagementParams?.caseDefinitionVersionTag ?? '', this.canInitializeDocument$.getValue(), this.startableByUser$.getValue());
|
|
1221
1314
|
}
|
|
1222
1315
|
if (context === 'buildingBlock') {
|
|
1223
1316
|
const buildingBlockManagementParams = params;
|
|
1224
|
-
return this.processLinkService.updateProcessDefinitionForBuildingBlock(processLinks, selectedProcessDefinition.id, result?.xml, buildingBlockManagementParams.buildingBlockDefinitionKey, buildingBlockManagementParams.buildingBlockDefinitionVersionTag);
|
|
1317
|
+
return this.processLinkService.updateProcessDefinitionForBuildingBlock(processLinks, selectedProcessDefinition.id, this.applyDraftState(result?.xml), buildingBlockManagementParams.buildingBlockDefinitionKey, buildingBlockManagementParams.buildingBlockDefinitionVersionTag);
|
|
1225
1318
|
}
|
|
1226
|
-
return this.processLinkService.updateProcessDefinition(processLinks, selectedProcessDefinition.id,
|
|
1319
|
+
return this.processLinkService.updateProcessDefinition(processLinks, selectedProcessDefinition.id, xml);
|
|
1227
1320
|
}), switchMap(() => this.context$))
|
|
1228
1321
|
.subscribe({
|
|
1229
1322
|
next: context => {
|
|
1323
|
+
this.clearValidationErrors();
|
|
1230
1324
|
if (context === 'independent') {
|
|
1231
1325
|
this.reload();
|
|
1232
1326
|
this.showNotification('success');
|
|
@@ -1235,12 +1329,20 @@ class ProcessManagementBuilderComponent {
|
|
|
1235
1329
|
this.navigateBack('success');
|
|
1236
1330
|
}
|
|
1237
1331
|
},
|
|
1238
|
-
error: () => {
|
|
1239
|
-
this.
|
|
1332
|
+
error: (error) => {
|
|
1333
|
+
if (this.isValidationError(error)) {
|
|
1334
|
+
this.highlightValidationErrors(error.error.errors);
|
|
1335
|
+
}
|
|
1336
|
+
else {
|
|
1337
|
+
this.showNotification('error');
|
|
1338
|
+
}
|
|
1240
1339
|
},
|
|
1241
1340
|
});
|
|
1242
1341
|
}
|
|
1243
1342
|
deployNewProcessDefinition() {
|
|
1343
|
+
this.validateAndDeploy(false, () => this.executeDeployNewProcessDefinition());
|
|
1344
|
+
}
|
|
1345
|
+
executeDeployNewProcessDefinition() {
|
|
1244
1346
|
combineLatest([
|
|
1245
1347
|
from(this._bpmnModeler.saveXML()),
|
|
1246
1348
|
this.processManagementEditorService.processLinksForSelectedDefinition$,
|
|
@@ -1248,29 +1350,34 @@ class ProcessManagementBuilderComponent {
|
|
|
1248
1350
|
this.managementParams$.pipe(startWith(null)),
|
|
1249
1351
|
])
|
|
1250
1352
|
.pipe(take(1), switchMap(([result, processLinks, context, params]) => {
|
|
1353
|
+
const xml = this.applyDraftState(result.xml ?? '');
|
|
1251
1354
|
const mappedProcessLinks = processLinks.map(link => ({
|
|
1252
1355
|
...link,
|
|
1253
1356
|
processDefinitionId: '-',
|
|
1254
1357
|
}));
|
|
1255
1358
|
switch (context) {
|
|
1256
1359
|
case 'independent':
|
|
1257
|
-
return this.processLinkService.createProcessDefinition(mappedProcessLinks,
|
|
1360
|
+
return this.processLinkService.createProcessDefinition(mappedProcessLinks, xml);
|
|
1258
1361
|
case 'buildingBlock':
|
|
1259
1362
|
const buildingBlockParams = params;
|
|
1260
|
-
return this.processLinkService.createProcessDefinitionForBuildingBlock(mappedProcessLinks,
|
|
1363
|
+
return this.processLinkService.createProcessDefinitionForBuildingBlock(mappedProcessLinks, xml, buildingBlockParams.buildingBlockDefinitionKey, buildingBlockParams.buildingBlockDefinitionVersionTag);
|
|
1261
1364
|
case 'case':
|
|
1262
1365
|
const caseManagementParams = params;
|
|
1263
|
-
return this.processLinkService.createProcessDefinitionForCase(mappedProcessLinks,
|
|
1366
|
+
return this.processLinkService.createProcessDefinitionForCase(mappedProcessLinks, xml, caseManagementParams.caseDefinitionKey, caseManagementParams.caseDefinitionVersionTag, this.canInitializeDocument$.getValue(), this.startableByUser$.getValue());
|
|
1264
1367
|
}
|
|
1265
1368
|
}))
|
|
1266
1369
|
.subscribe({
|
|
1267
1370
|
next: () => {
|
|
1371
|
+
this.clearValidationErrors();
|
|
1268
1372
|
this.navigateBack('success');
|
|
1269
1373
|
},
|
|
1270
1374
|
error: (error) => {
|
|
1271
1375
|
if (this.isProcessDefinitionAlreadyExistsError(error)) {
|
|
1272
1376
|
this.showNotification('alreadyExists');
|
|
1273
1377
|
}
|
|
1378
|
+
else if (this.isValidationError(error)) {
|
|
1379
|
+
this.highlightValidationErrors(error.error.errors);
|
|
1380
|
+
}
|
|
1274
1381
|
else {
|
|
1275
1382
|
this.showNotification('error');
|
|
1276
1383
|
}
|
|
@@ -1293,13 +1400,88 @@ class ProcessManagementBuilderComponent {
|
|
|
1293
1400
|
return;
|
|
1294
1401
|
this.showNotification(notification);
|
|
1295
1402
|
}
|
|
1403
|
+
onValidationErrorClick(elementId) {
|
|
1404
|
+
const modeler = this.isReadOnlyProcess$.getValue() ? this._bpmnViewer : this._bpmnModeler;
|
|
1405
|
+
const elementRegistry = modeler.get('elementRegistry');
|
|
1406
|
+
const canvas = modeler.get('canvas');
|
|
1407
|
+
const element = elementRegistry.get(elementId);
|
|
1408
|
+
if (!element)
|
|
1409
|
+
return;
|
|
1410
|
+
try {
|
|
1411
|
+
const selection = modeler.get('selection');
|
|
1412
|
+
selection?.select?.(element);
|
|
1413
|
+
}
|
|
1414
|
+
catch {
|
|
1415
|
+
// Viewer may not expose the selection service.
|
|
1416
|
+
}
|
|
1417
|
+
try {
|
|
1418
|
+
canvas.scrollToElement(element);
|
|
1419
|
+
}
|
|
1420
|
+
catch {
|
|
1421
|
+
// ignore
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1296
1424
|
onProcessToggleChange(field, value) {
|
|
1425
|
+
if (field === 'draft')
|
|
1426
|
+
this.draft$.next(value);
|
|
1297
1427
|
if (field === 'canInitializeDocument')
|
|
1298
1428
|
this.canInitializeDocument$.next(value);
|
|
1299
1429
|
if (field === 'startableByUser')
|
|
1300
1430
|
this.startableByUser$.next(value);
|
|
1301
1431
|
this.changesPending$.next(true);
|
|
1302
1432
|
}
|
|
1433
|
+
onWarningConfirmationConfirm() {
|
|
1434
|
+
if (this._pendingDeployAction) {
|
|
1435
|
+
this._pendingDeployAction();
|
|
1436
|
+
this._pendingDeployAction = null;
|
|
1437
|
+
}
|
|
1438
|
+
}
|
|
1439
|
+
onWarningConfirmationCancel() {
|
|
1440
|
+
this._pendingDeployAction = null;
|
|
1441
|
+
}
|
|
1442
|
+
validateAndDeploy(isReadOnlyProcess, deployAction) {
|
|
1443
|
+
// Skip validation for draft processes
|
|
1444
|
+
if (this.draft$.getValue()) {
|
|
1445
|
+
deployAction();
|
|
1446
|
+
return;
|
|
1447
|
+
}
|
|
1448
|
+
combineLatest([
|
|
1449
|
+
from(isReadOnlyProcess ? this._bpmnViewer.saveXML() : this._bpmnModeler.saveXML()),
|
|
1450
|
+
this.processManagementEditorService.processLinksForSelectedDefinition$,
|
|
1451
|
+
])
|
|
1452
|
+
.pipe(take(1), switchMap(([result, processLinks]) => {
|
|
1453
|
+
const xml = this.applyDraftState(result?.xml ?? '') ?? '';
|
|
1454
|
+
return this.processManagementService.validateProcessDefinition({
|
|
1455
|
+
bpmnXml: xml,
|
|
1456
|
+
processLinks: processLinks.map(link => ({
|
|
1457
|
+
...link,
|
|
1458
|
+
processDefinitionId: '-',
|
|
1459
|
+
})),
|
|
1460
|
+
});
|
|
1461
|
+
}))
|
|
1462
|
+
.subscribe({
|
|
1463
|
+
next: validationResult => {
|
|
1464
|
+
if (!validationResult.isValid) {
|
|
1465
|
+
// Has errors - show them and block deployment
|
|
1466
|
+
this.highlightValidationErrors(validationResult.errors);
|
|
1467
|
+
}
|
|
1468
|
+
else if (validationResult.hasWarnings) {
|
|
1469
|
+
// Only warnings - show confirmation dialog
|
|
1470
|
+
this.highlightValidationErrors(validationResult.errors);
|
|
1471
|
+
this._pendingDeployAction = deployAction;
|
|
1472
|
+
this.showWarningConfirmationModal$.next(true);
|
|
1473
|
+
}
|
|
1474
|
+
else {
|
|
1475
|
+
// No issues - proceed with deployment
|
|
1476
|
+
deployAction();
|
|
1477
|
+
}
|
|
1478
|
+
},
|
|
1479
|
+
error: () => {
|
|
1480
|
+
// Validation endpoint failed - proceed with deployment anyway (server will validate again)
|
|
1481
|
+
deployAction();
|
|
1482
|
+
},
|
|
1483
|
+
});
|
|
1484
|
+
}
|
|
1303
1485
|
setProcessManagementWindow() {
|
|
1304
1486
|
const processManagementWindow = window;
|
|
1305
1487
|
if (!processManagementWindow)
|
|
@@ -1309,7 +1491,20 @@ class ProcessManagementBuilderComponent {
|
|
|
1309
1491
|
processManagementWindow.pluginTranslationService = this.pluginTranslationService;
|
|
1310
1492
|
}
|
|
1311
1493
|
showNotification(notification) {
|
|
1312
|
-
|
|
1494
|
+
if (!notification)
|
|
1495
|
+
return;
|
|
1496
|
+
let type;
|
|
1497
|
+
if (notification === 'alreadyExists' ||
|
|
1498
|
+
notification === 'validationError' ||
|
|
1499
|
+
notification === 'error') {
|
|
1500
|
+
type = 'error';
|
|
1501
|
+
}
|
|
1502
|
+
else if (notification === 'validationWarning') {
|
|
1503
|
+
type = 'warning';
|
|
1504
|
+
}
|
|
1505
|
+
else {
|
|
1506
|
+
type = 'success';
|
|
1507
|
+
}
|
|
1313
1508
|
this.notificationService.showToast({
|
|
1314
1509
|
caption: this.translateService.instant(`processManagement.${notification}Notification`),
|
|
1315
1510
|
type,
|
|
@@ -1323,7 +1518,148 @@ class ProcessManagementBuilderComponent {
|
|
|
1323
1518
|
if (body?.processDefinitionId)
|
|
1324
1519
|
return true;
|
|
1325
1520
|
const bbBody = body;
|
|
1326
|
-
return Array.isArray(bbBody?.duplicateProcessDefinitions) &&
|
|
1521
|
+
return (Array.isArray(bbBody?.duplicateProcessDefinitions) &&
|
|
1522
|
+
bbBody.duplicateProcessDefinitions.length > 0);
|
|
1523
|
+
}
|
|
1524
|
+
applyDraftState(xml) {
|
|
1525
|
+
if (!xml)
|
|
1526
|
+
return null;
|
|
1527
|
+
const doc = new DOMParser().parseFromString(xml, 'application/xml');
|
|
1528
|
+
if (doc.getElementsByTagName('parsererror').length > 0)
|
|
1529
|
+
return xml;
|
|
1530
|
+
const executableValue = this.draft$.getValue() ? 'false' : 'true';
|
|
1531
|
+
const processes = doc.getElementsByTagNameNS('*', 'process');
|
|
1532
|
+
for (let i = 0; i < processes.length; i++) {
|
|
1533
|
+
processes[i].setAttribute('isExecutable', executableValue);
|
|
1534
|
+
}
|
|
1535
|
+
return new XMLSerializer().serializeToString(doc);
|
|
1536
|
+
}
|
|
1537
|
+
parseDraftFromXml(xml) {
|
|
1538
|
+
if (!xml)
|
|
1539
|
+
return false;
|
|
1540
|
+
const doc = new DOMParser().parseFromString(xml, 'application/xml');
|
|
1541
|
+
if (doc.getElementsByTagName('parsererror').length > 0)
|
|
1542
|
+
return false;
|
|
1543
|
+
const processes = doc.getElementsByTagNameNS('*', 'process');
|
|
1544
|
+
if (processes.length === 0)
|
|
1545
|
+
return false;
|
|
1546
|
+
for (let i = 0; i < processes.length; i++) {
|
|
1547
|
+
if (processes[i].getAttribute('isExecutable') === 'true')
|
|
1548
|
+
return false;
|
|
1549
|
+
}
|
|
1550
|
+
return true;
|
|
1551
|
+
}
|
|
1552
|
+
isValidationError(error) {
|
|
1553
|
+
return (error instanceof HttpErrorResponse &&
|
|
1554
|
+
error.status === 422 &&
|
|
1555
|
+
Array.isArray(error.error?.errors));
|
|
1556
|
+
}
|
|
1557
|
+
highlightValidationErrors(errors) {
|
|
1558
|
+
this.clearValidationErrors();
|
|
1559
|
+
this.processManagementEditorService.setValidationErrors(errors);
|
|
1560
|
+
const modeler = this.isReadOnlyProcess$.getValue() ? this._bpmnViewer : this._bpmnModeler;
|
|
1561
|
+
const canvas = modeler.get('canvas');
|
|
1562
|
+
const overlays = modeler.get('overlays');
|
|
1563
|
+
const errorElementIds = new Set();
|
|
1564
|
+
const elementHasError = new Map();
|
|
1565
|
+
const elementFirstIssue = new Map();
|
|
1566
|
+
for (const error of errors) {
|
|
1567
|
+
if (error.elementType === 'Process')
|
|
1568
|
+
continue;
|
|
1569
|
+
const hasErrorAlready = elementHasError.get(error.elementId) ?? false;
|
|
1570
|
+
const isError = error.severity !== 'WARNING';
|
|
1571
|
+
if (!elementFirstIssue.has(error.elementId)) {
|
|
1572
|
+
elementFirstIssue.set(error.elementId, error);
|
|
1573
|
+
}
|
|
1574
|
+
else if (isError && !hasErrorAlready) {
|
|
1575
|
+
elementFirstIssue.set(error.elementId, error);
|
|
1576
|
+
}
|
|
1577
|
+
if (isError) {
|
|
1578
|
+
elementHasError.set(error.elementId, true);
|
|
1579
|
+
}
|
|
1580
|
+
else if (!hasErrorAlready) {
|
|
1581
|
+
elementHasError.set(error.elementId, false);
|
|
1582
|
+
}
|
|
1583
|
+
}
|
|
1584
|
+
for (const [elementId, issue] of elementFirstIssue) {
|
|
1585
|
+
try {
|
|
1586
|
+
const hasError = elementHasError.get(elementId) ?? false;
|
|
1587
|
+
const markerClass = hasError ? 'highlight-overlay-error' : 'highlight-overlay-warning';
|
|
1588
|
+
const overlayClass = hasError ? 'validation-error-overlay' : 'validation-warning-overlay';
|
|
1589
|
+
this._validationErrorElementIds.push(elementId);
|
|
1590
|
+
errorElementIds.add(elementId);
|
|
1591
|
+
canvas.addMarker(elementId, markerClass);
|
|
1592
|
+
const position = issue.elementType === 'Participant' ? { top: 5, left: 5 } : { top: -12, left: -12 };
|
|
1593
|
+
overlays.add(elementId, 'validation-error', {
|
|
1594
|
+
position,
|
|
1595
|
+
html: this.buildOverlayElement(overlayClass, elementId, this.getValidationErrorMessage(issue)),
|
|
1596
|
+
});
|
|
1597
|
+
}
|
|
1598
|
+
catch (e) {
|
|
1599
|
+
// Element may not exist on the canvas
|
|
1600
|
+
}
|
|
1601
|
+
}
|
|
1602
|
+
const eventBus = modeler.get('eventBus');
|
|
1603
|
+
this._validationHoverHandler = (event) => {
|
|
1604
|
+
const id = event.element?.id;
|
|
1605
|
+
if (id && errorElementIds.has(id)) {
|
|
1606
|
+
const errorOverlay = document.querySelector(`.validation-error-overlay[data-element-id="${id}"]`);
|
|
1607
|
+
const warningOverlay = document.querySelector(`.validation-warning-overlay[data-element-id="${id}"]`);
|
|
1608
|
+
errorOverlay?.classList.add('validation-error-overlay--active');
|
|
1609
|
+
warningOverlay?.classList.add('validation-warning-overlay--active');
|
|
1610
|
+
}
|
|
1611
|
+
};
|
|
1612
|
+
this._validationOutHandler = (event) => {
|
|
1613
|
+
const id = event.element?.id;
|
|
1614
|
+
if (id && errorElementIds.has(id)) {
|
|
1615
|
+
const errorOverlay = document.querySelector(`.validation-error-overlay[data-element-id="${id}"]`);
|
|
1616
|
+
const warningOverlay = document.querySelector(`.validation-warning-overlay[data-element-id="${id}"]`);
|
|
1617
|
+
errorOverlay?.classList.remove('validation-error-overlay--active');
|
|
1618
|
+
warningOverlay?.classList.remove('validation-warning-overlay--active');
|
|
1619
|
+
}
|
|
1620
|
+
};
|
|
1621
|
+
eventBus.on('element.hover', this._validationHoverHandler);
|
|
1622
|
+
eventBus.on('element.out', this._validationOutHandler);
|
|
1623
|
+
const selection = modeler.get('selection');
|
|
1624
|
+
const selected = selection.get();
|
|
1625
|
+
if (selected?.length > 0) {
|
|
1626
|
+
const current = selected[0];
|
|
1627
|
+
selection.deselect(current);
|
|
1628
|
+
selection.select(current);
|
|
1629
|
+
}
|
|
1630
|
+
}
|
|
1631
|
+
clearValidationErrors() {
|
|
1632
|
+
const modeler = this.isReadOnlyProcess$.getValue() ? this._bpmnViewer : this._bpmnModeler;
|
|
1633
|
+
if (!modeler)
|
|
1634
|
+
return;
|
|
1635
|
+
this.processManagementEditorService.setValidationErrors([]);
|
|
1636
|
+
const canvas = modeler.get('canvas');
|
|
1637
|
+
const overlays = modeler.get('overlays');
|
|
1638
|
+
const eventBus = modeler.get('eventBus');
|
|
1639
|
+
if (this._validationHoverHandler) {
|
|
1640
|
+
eventBus.off('element.hover', this._validationHoverHandler);
|
|
1641
|
+
this._validationHoverHandler = null;
|
|
1642
|
+
}
|
|
1643
|
+
if (this._validationOutHandler) {
|
|
1644
|
+
eventBus.off('element.out', this._validationOutHandler);
|
|
1645
|
+
this._validationOutHandler = null;
|
|
1646
|
+
}
|
|
1647
|
+
for (const elementId of this._validationErrorElementIds) {
|
|
1648
|
+
try {
|
|
1649
|
+
canvas.removeMarker(elementId, 'highlight-overlay-error');
|
|
1650
|
+
canvas.removeMarker(elementId, 'highlight-overlay-warning');
|
|
1651
|
+
}
|
|
1652
|
+
catch (e) {
|
|
1653
|
+
// ignore
|
|
1654
|
+
}
|
|
1655
|
+
}
|
|
1656
|
+
this._validationErrorElementIds = [];
|
|
1657
|
+
try {
|
|
1658
|
+
overlays.remove({ type: 'validation-error' });
|
|
1659
|
+
}
|
|
1660
|
+
catch (e) {
|
|
1661
|
+
// ignore
|
|
1662
|
+
}
|
|
1327
1663
|
}
|
|
1328
1664
|
setSelectedProcessDefinitionToLatest(processDefinitions) {
|
|
1329
1665
|
const latest = getLatestProcessDefinition(processDefinitions);
|
|
@@ -1475,6 +1811,8 @@ class ProcessManagementBuilderComponent {
|
|
|
1475
1811
|
this.cleanUpListenersOnModeler();
|
|
1476
1812
|
this._bpmnModeler?.importXML(processDefinitionResult.bpmn20Xml);
|
|
1477
1813
|
this._bpmnViewer?.importXML(processDefinitionResult.bpmn20Xml);
|
|
1814
|
+
this.draft$.next(processDefinitionResult.draft ??
|
|
1815
|
+
this.parseDraftFromXml(processDefinitionResult.bpmn20Xml));
|
|
1478
1816
|
this.canInitializeDocument$.next(!!processDefinitionResult?.processCaseLink?.canInitializeDocument);
|
|
1479
1817
|
this.startableByUser$.next(!!processDefinitionResult?.processCaseLink?.startableByUser);
|
|
1480
1818
|
this.loading$.next(false);
|
|
@@ -1551,13 +1889,37 @@ class ProcessManagementBuilderComponent {
|
|
|
1551
1889
|
}
|
|
1552
1890
|
clearBuildingBlockCalledElement(editor, activityId);
|
|
1553
1891
|
}
|
|
1892
|
+
getValidationErrorMessage(error) {
|
|
1893
|
+
if (error.errorCode) {
|
|
1894
|
+
const translationKey = `processManagement.expressionErrors.${error.errorCode}`;
|
|
1895
|
+
const translated = this.translateService.instant(translationKey);
|
|
1896
|
+
if (translated !== translationKey) {
|
|
1897
|
+
return error.expression ? `${translated}: '${error.expression}'` : translated;
|
|
1898
|
+
}
|
|
1899
|
+
}
|
|
1900
|
+
return error.reason;
|
|
1901
|
+
}
|
|
1902
|
+
buildOverlayElement(overlayClass, elementId, message) {
|
|
1903
|
+
const container = document.createElement('div');
|
|
1904
|
+
container.className = overlayClass;
|
|
1905
|
+
container.dataset.elementId = elementId;
|
|
1906
|
+
const icon = document.createElement('span');
|
|
1907
|
+
icon.className = `${overlayClass}__icon`;
|
|
1908
|
+
icon.textContent = '!';
|
|
1909
|
+
container.appendChild(icon);
|
|
1910
|
+
const text = document.createElement('span');
|
|
1911
|
+
text.className = `${overlayClass}__text`;
|
|
1912
|
+
text.textContent = message;
|
|
1913
|
+
container.appendChild(text);
|
|
1914
|
+
return container;
|
|
1915
|
+
}
|
|
1554
1916
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: ProcessManagementBuilderComponent, deps: [{ token: i1$1.BreadcrumbService }, { token: i2$2.IconService }, { token: i3.NGXLogger }, { token: i1$1.ModalService }, { token: i2$1.GlobalNotificationService }, { token: i1$1.PageHeaderService }, { token: i1$1.PageTitleService }, { token: i5.ProcessLinkService }, { token: i5.ProcessLinkStateService }, { token: ProcessManagementEditorService }, { token: ProcessManagementService }, { token: i7.ProcessService }, { token: i8.ActivatedRoute }, { token: i8.Router }, { token: i9.TranslateService }, { token: i10.PluginTranslationService }, { token: i2$1.EditPermissionsService }, { token: i5.ProcessLinkBuildingBlockApiService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1555
1917
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.20", type: ProcessManagementBuilderComponent, isStandalone: true, selector: "valtimo-process-management-builder", providers: [
|
|
1556
1918
|
ProcessManagementEditorService,
|
|
1557
1919
|
ProcessLinkStateService,
|
|
1558
1920
|
ProcessLinkStepService,
|
|
1559
1921
|
ProcessLinkButtonService,
|
|
1560
|
-
], viewQueries: [{ propertyName: "modelerElementRef", first: true, predicate: ["modeler"], descendants: true }, { propertyName: "modelerPanelElementRef", first: true, predicate: ["modelerPanel"], descendants: true }, { propertyName: "viewerElementRef", first: true, predicate: ["viewer"], descendants: true }, { propertyName: "viewerPanelElementRef", first: true, predicate: ["viewerPanel"], descendants: true }], ngImport: i0, template: "<!--\n ~ Copyright 2015-2025 Ritense BV, the Netherlands.\n ~\n ~ Licensed under EUPL, Version 1.2 (the \"License\");\n ~ you may not use this file except in compliance with the License.\n ~ You may obtain a copy of the License at\n ~\n ~ https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12\n ~\n ~ Unless required by applicable law or agreed to in writing, software\n ~ distributed under the License is distributed on an \"AS IS\" basis,\n ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ~ See the License for the specific language governing permissions and\n ~ limitations under the License.\n -->\n\n<div\n fitPage\n [spaceAdjustment]=\"$spaceAdjustment()\"\n [disableOverflow]=\"true\"\n *ngIf=\"{\n processDefinitionVersions: processDefinitionVersions$ | async,\n selectedProcessDefinitionXml: selectedProcessDefinitionXml$ | async,\n loading: loading$ | async,\n isReadOnlyProcess: isReadOnlyProcess$ | async,\n hasEditPermissions: hasEditPermissions$ | async,\n } as obs\"\n data-carbon-theme=\"g10\"\n class=\"bpmn__container\"\n>\n <div\n class=\"bpmn__modeler\"\n [style.display]=\"obs.isReadOnlyProcess || !obs.hasEditPermissions ? 'none' : 'flex'\"\n >\n <div class=\"bpmn__modeler-canvas\" #modeler></div>\n\n <div class=\"bpmn__modeler-panel\" #modelerPanel></div>\n </div>\n\n <div\n class=\"bpmn__modeler\"\n [style.display]=\"obs.isReadOnlyProcess || !obs.hasEditPermissions ? 'flex' : 'none'\"\n >\n <div class=\"bpmn__modeler-canvas\" #viewer></div>\n\n <div class=\"bpmn__modeler-panel\" #viewerPanel></div>\n </div>\n</div>\n\n<valtimo-process-link-modal></valtimo-process-link-modal>\n\n<ng-container renderInPageHeader [fullWidth]=\"true\">\n <ng-template>\n <div\n class=\"page-header-actions\"\n *ngIf=\"{\n processDefinitionVersionsListItems: processDefinitionVersionsListItems$ | async,\n loading: loading$ | async,\n changesPending: changesPending$ | async,\n isReadOnlyProcess: isReadOnlyProcess$ | async,\n isSystemProcess: isSystemProcess$ | async,\n compactMode: compactMode$ | async,\n creatingNewProcess: creatingNewProcess$ | async,\n context: context$ | async,\n hasEditPermissions: hasEditPermissions$ | async,\n canInitializeDocument: canInitializeDocument$ | async,\n startableByUser: startableByUser$ | async,\n updatingProcessDefinitionCaseDefinition: updatingProcessDefinitionCaseDefinition$ | async,\n } as actionsObs\"\n >\n <div class=\"page-header-actions__left-container\">\n <cds-dropdown\n *ngIf=\"!actionsObs.creatingNewProcess && actionsObs?.context === 'independent'\"\n class=\"page-header-actions__version-dropdown\"\n (selected)=\"selectedVersionChange($event)\"\n [disabled]=\"\n actionsObs.loading ||\n (actionsObs.processDefinitionVersionsListItems || []).length === 0 ||\n (actionsObs.processDefinitionVersionsListItems || []).length === 1\n \"\n [size]=\"actionsObs.compactMode ? 'sm' : 'md'\"\n >\n <cds-dropdown-list\n [items]=\"actionsObs.processDefinitionVersionsListItems || []\"\n ></cds-dropdown-list>\n </cds-dropdown>\n\n <div class=\"page-header-actions__tags\">\n <cds-tag\n *ngIf=\"actionsObs.isReadOnlyProcess || !actionsObs.hasEditPermissions\"\n type=\"blue\"\n >{{ 'processManagement.readOnly' | translate }}</cds-tag\n >\n\n <cds-tag *ngIf=\"actionsObs.isSystemProcess\" type=\"red\">{{\n 'processManagement.systemProcess' | translate\n }}</cds-tag>\n </div>\n </div>\n\n <div class=\"page-header-actions__buttons\">\n @if (actionsObs.context === 'case') {\n <cds-tooltip\n [description]=\"'processCaseConnection.processCreatesCaseTooltip' | translate\"\n >\n <cds-toggle\n [onText]=\"'processManagement.canInitializeDocument' | translate\"\n [offText]=\"'processManagement.canInitializeDocument' | translate\"\n [checked]=\"actionsObs.canInitializeDocument\"\n [disabled]=\"\n actionsObs.loading ||\n actionsObs.updatingProcessDefinitionCaseDefinition ||\n !actionsObs.hasEditPermissions\n \"\n (checkedChange)=\"onProcessToggleChange('canInitializeDocument', $event)\"\n [attr.data-test-id]=\"testIds.startsCaseToggle\"\n ></cds-toggle>\n </cds-tooltip>\n\n <cds-tooltip\n [description]=\"'processCaseConnection.startableWithinCaseTooltip' | translate\"\n >\n <cds-toggle\n [onText]=\"'processManagement.startableByUser' | translate\"\n [offText]=\"'processManagement.startableByUser' | translate\"\n [checked]=\"actionsObs.startableByUser\"\n [disabled]=\"\n actionsObs.loading ||\n actionsObs.updatingProcessDefinitionCaseDefinition ||\n !actionsObs.hasEditPermissions\n \"\n (checkedChange)=\"onProcessToggleChange('startableByUser', $event)\"\n [attr.data-test-id]=\"testIds.startableByUserToggle\"\n ></cds-toggle\n ></cds-tooltip>\n }\n\n <button\n *ngIf=\"actionsObs.context === 'case'\"\n cdsButton=\"secondary\"\n [size]=\"actionsObs.compactMode ? 'sm' : 'md'\"\n (click)=\"navigateBack(null)\"\n >\n <svg class=\"cds--btn__icon\" cdsIcon=\"arrow--left\" size=\"16\"></svg>\n\n <span>{{ 'interface.back' | translate }}</span>\n </button>\n\n <button\n [disabled]=\"!actionsObs.changesPending\"\n cdsButton=\"primary\"\n (click)=\"\n !actionsObs.creatingNewProcess\n ? deployChanges(actionsObs.isReadOnlyProcess)\n : deployNewProcessDefinition()\n \"\n [size]=\"actionsObs.compactMode ? 'sm' : 'md'\"\n [attr.data-test-id]=\"testIds.deployButton\"\n >\n {{ 'processManagement.deploy' | translate }}\n\n <svg class=\"cds--btn__icon\" cdsIcon=\"deploy\" size=\"16\"></svg>\n </button>\n\n <v-overflow-menu class=\"overflow-button\" placement=\"bottom-end\">\n <v-overflow-menu-trigger overflowTrigger></v-overflow-menu-trigger>\n <v-overflow-menu-option\n [disabled]=\"actionsObs.loading\"\n (selected)=\"export(actionsObs.isReadOnlyProcess)\"\n >{{ 'interface.export' | translate }}\n </v-overflow-menu-option>\n </v-overflow-menu>\n </div>\n </div>\n </ng-template>\n</ng-container>\n", styles: [":host{display:flex;flex-direction:column;gap:24px}.bpmn__container{position:relative;background-color:var(--cds-layer);width:100%}.bpmn__modeler{width:100%;height:100%;flex-direction:row;padding:1px;box-sizing:border-box;outline:1px solid var(--cds-border-subtle);outline-offset:-1px}.bpmn__modeler ::ng-deep .djs-container>svg{outline:none!important}.bpmn__modeler-canvas{width:100%}.bpmn__modeler-panel{width:481px;padding-left:1px;box-shadow:inset 1px 0 0 0 var(--cds-border-subtle);box-sizing:border-box}.bpmn__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}.page-header-actions__left-container{display:flex;gap:24px;align-items:flex-end}.page-header-actions__tags{display:flex;gap:8px;align-items:flex-end}.page-header-actions__version-dropdown{width:150px}.page-header-actions__buttons{display:flex;gap:16px;align-items:center}.page-header-actions__buttons cds-toggle{height:24px}.page-header-actions__buttons ::ng-deep .cds--toggle__label-text{display:none}.valtimo-process-builder__header{display:flex;justify-content:space-between}.valtimo-process-builder__actions>*:not(:last-child){margin-right:8px}::ng-deep .process-link-properties-panel{padding:8px 12px 16px;width:100%;display:flex;flex-direction:column;gap:16px}::ng-deep .process-link-properties-panel__buttons,::ng-deep .process-link-properties-panel__header{width:100%;display:flex;gap:16px}::ng-deep .process-link-properties-panel__header{align-items:flex-start;justify-content:space-between;border-bottom:1px solid var(--cds-border-subtle-00);padding-bottom:8px;padding-left:8px;padding-right:8px}::ng-deep .process-link-properties-panel__title{color:var(--cds-text-secondary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:200px;margin:auto 0}::ng-deep .process-link-properties-panel__title-container{display:flex;flex-direction:column;gap:4px}::ng-deep .process-link-properties-panel__title-container :last-child{color:var(--cds-text-helper);font-style:italic}::ng-deep .process-link-properties-panel .cds--tag{margin:0}::ng-deep .process-link-properties-panel .cds--btn{flex-shrink:1;width:100%;display:flex;align-items:center}\n/*!\n * Copyright 2015-2025 Ritense BV, the Netherlands.\n *\n * Licensed under EUPL, Version 1.2 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i6.AsyncPipe, name: "async" }, { kind: "directive", type: FitPageDirective, selector: "[fitPage]", inputs: ["spaceAdjustment", "fitPageDisabled", "disableOverflow"] }, { kind: "ngmodule", type: LoadingModule }, { kind: "directive", type: RenderInPageHeaderDirective, selector: "[renderInPageHeader]", inputs: ["fullWidth"] }, { kind: "ngmodule", type: DropdownModule }, { kind: "component", type: i2$2.Dropdown, selector: "cds-dropdown, ibm-dropdown", inputs: ["id", "label", "hideLabel", "helperText", "placeholder", "displayValue", "clearText", "size", "type", "theme", "disabled", "readonly", "skeleton", "inline", "disableArrowKeys", "invalid", "invalidText", "warn", "warnText", "appendInline", "scrollableContainer", "itemValueKey", "selectionFeedback", "menuButtonLabel", "selectedLabel", "dropUp", "fluid"], outputs: ["selected", "onClose", "close"] }, { kind: "component", type: i2$2.DropdownList, selector: "cds-dropdown-list, ibm-dropdown-list", inputs: ["ariaLabel", "items", "listTpl", "type", "showTitles"], outputs: ["select", "scroll", "blurIntent"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: SelectModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2$2.Button, selector: "[cdsButton], [ibmButton]", inputs: ["ibmButton", "cdsButton", "size", "skeleton", "iconOnly", "isExpressive"] }, { kind: "ngmodule", type: IconModule }, { kind: "directive", type: i2$2.IconDirective, selector: "[cdsIcon], [ibmIcon]", inputs: ["ibmIcon", "cdsIcon", "size", "title", "ariaLabel", "ariaLabelledBy", "ariaHidden", "isFocusable"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i9.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: TagModule }, { kind: "component", type: i2$2.Tag, selector: "cds-tag, ibm-tag", inputs: ["type", "size", "class", "skeleton"] }, { kind: "ngmodule", type: ProcessLinkModule }, { kind: "component", type: i5.ProcessLinkModalComponent, selector: "valtimo-process-link-modal" }, { kind: "component", type: OverflowMenuComponent, selector: "v-overflow-menu", inputs: ["open", "placement", "menuWidth", "offsetX", "offsetY", "closeOnSelect", "useHostAsReference", "portalToBody"], outputs: ["openChange"] }, { kind: "component", type: OverflowMenuOptionComponent, selector: "v-overflow-menu-option", inputs: ["disabled", "type", "testId", "optionId"], outputs: ["selected"] }, { kind: "component", type: OverflowMenuTriggerComponent, selector: "v-overflow-menu-trigger", inputs: ["compact"] }, { kind: "ngmodule", type: ToggleModule }, { kind: "component", type: i2$2.Toggle, selector: "cds-toggle, ibm-toggle", inputs: ["offText", "onText", "label", "size", "hideLabel", "ariaLabel", "skeleton"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "component", type: i2$2.Tooltip, selector: "cds-tooltip, ibm-tooltip", inputs: ["id", "enterDelayMs", "leaveDelayMs", "disabled", "description", "templateContext"] }] }); }
|
|
1922
|
+
], viewQueries: [{ propertyName: "modelerElementRef", first: true, predicate: ["modeler"], descendants: true }, { propertyName: "modelerPanelElementRef", first: true, predicate: ["modelerPanel"], descendants: true }, { propertyName: "viewerElementRef", first: true, predicate: ["viewer"], descendants: true }, { propertyName: "viewerPanelElementRef", first: true, predicate: ["viewerPanel"], descendants: true }], ngImport: i0, template: "<!--\n ~ Copyright 2015-2026 Ritense BV, the Netherlands.\n ~\n ~ Licensed under EUPL, Version 1.2 (the \"License\");\n ~ you may not use this file except in compliance with the License.\n ~ You may obtain a copy of the License at\n ~\n ~ https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12\n ~\n ~ Unless required by applicable law or agreed to in writing, software\n ~ distributed under the License is distributed on an \"AS IS\" basis,\n ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ~ See the License for the specific language governing permissions and\n ~ limitations under the License.\n -->\n\n<div\n fitPage\n [disableOverflow]=\"true\"\n *ngIf=\"{\n processDefinitionVersions: processDefinitionVersions$ | async,\n selectedProcessDefinitionXml: selectedProcessDefinitionXml$ | async,\n loading: loading$ | async,\n isReadOnlyProcess: isReadOnlyProcess$ | async,\n hasEditPermissions: hasEditPermissions$ | async,\n } as obs\"\n data-carbon-theme=\"g10\"\n class=\"bpmn__container\"\n>\n <div\n class=\"bpmn__modeler\"\n [style.display]=\"obs.isReadOnlyProcess || !obs.hasEditPermissions ? 'none' : 'flex'\"\n >\n <div class=\"bpmn__modeler-canvas\" #modeler>\n <div\n class=\"validation-errors-list\"\n *ngIf=\"validationErrors$ | async as validationErrors\"\n [style.display]=\"validationErrors.length > 0 ? '' : 'none'\"\n >\n <details open>\n <summary class=\"validation-errors-list__header\">\n <span>{{\n 'processManagement.validationErrorsCount'\n | translate: {count: validationErrors.length}\n }}</span>\n <svg\n class=\"validation-errors-list__arrow\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n >\n <path\n fill-rule=\"evenodd\"\n d=\"m11.657 8-4.95 4.95a1 1 0 0 1-1.414-1.414L8.828 8 5.293 4.464A1 1 0 1 1 6.707 3.05L11.657 8Z\"\n />\n </svg>\n </summary>\n\n <div class=\"validation-errors-list__items\">\n <button\n *ngFor=\"let error of validationErrors\"\n class=\"validation-errors-list__item\"\n [class.warning]=\"error.severity === 'WARNING'\"\n (click)=\"onValidationErrorClick(error.elementId)\"\n >\n <span\n class=\"validation-errors-list__icon\"\n [class.warning]=\"error.severity === 'WARNING'\"\n >{{ error.severity === 'WARNING' ? '!' : '!' }}</span\n >\n\n <span class=\"validation-errors-list__details\">\n <span class=\"validation-errors-list__element\">{{\n error.elementName || error.elementId\n }}</span>\n\n <span\n class=\"validation-errors-list__reason\"\n [class.warning]=\"error.severity === 'WARNING'\"\n >{{ getValidationErrorMessage(error) }}</span\n >\n </span>\n </button>\n </div>\n </details>\n </div>\n </div>\n\n <div class=\"bpmn__modeler-panel\" #modelerPanel></div>\n </div>\n\n <div\n class=\"bpmn__modeler\"\n [style.display]=\"obs.isReadOnlyProcess || !obs.hasEditPermissions ? 'flex' : 'none'\"\n >\n <div class=\"bpmn__modeler-canvas\" #viewer></div>\n\n <div class=\"bpmn__modeler-panel\" #viewerPanel></div>\n </div>\n</div>\n\n<valtimo-process-link-modal></valtimo-process-link-modal>\n\n<valtimo-confirmation-modal\n [showModalSubject$]=\"showWarningConfirmationModal$\"\n [titleTranslationKey]=\"'processManagement.warningConfirmation.title'\"\n [contentTranslationKey]=\"'processManagement.warningConfirmation.content'\"\n [confirmButtonTextTranslationKey]=\"'processManagement.warningConfirmation.confirm'\"\n [cancelButtonTextTranslationKey]=\"'interface.cancel'\"\n (confirmEvent)=\"onWarningConfirmationConfirm()\"\n (cancelEvent)=\"onWarningConfirmationCancel()\"\n></valtimo-confirmation-modal>\n\n<ng-container renderInPageHeader [fullWidth]=\"true\">\n <ng-template>\n <div\n class=\"page-header-actions\"\n *ngIf=\"{\n processDefinitionVersionsListItems: processDefinitionVersionsListItems$ | async,\n loading: loading$ | async,\n changesPending: changesPending$ | async,\n isReadOnlyProcess: isReadOnlyProcess$ | async,\n isSystemProcess: isSystemProcess$ | async,\n compactMode: compactMode$ | async,\n creatingNewProcess: creatingNewProcess$ | async,\n context: context$ | async,\n hasEditPermissions: hasEditPermissions$ | async,\n draft: draft$ | async,\n canInitializeDocument: canInitializeDocument$ | async,\n startableByUser: startableByUser$ | async,\n updatingProcessDefinitionCaseDefinition: updatingProcessDefinitionCaseDefinition$ | async,\n } as actionsObs\"\n >\n <div class=\"page-header-actions__left-container\">\n <cds-dropdown\n *ngIf=\"!actionsObs.creatingNewProcess && actionsObs?.context === 'independent'\"\n class=\"page-header-actions__version-dropdown\"\n (selected)=\"selectedVersionChange($event)\"\n [disabled]=\"\n actionsObs.loading ||\n (actionsObs.processDefinitionVersionsListItems || []).length === 0 ||\n (actionsObs.processDefinitionVersionsListItems || []).length === 1\n \"\n [size]=\"actionsObs.compactMode ? 'sm' : 'md'\"\n >\n <cds-dropdown-list\n [items]=\"actionsObs.processDefinitionVersionsListItems || []\"\n ></cds-dropdown-list>\n </cds-dropdown>\n\n <div\n class=\"page-header-actions__tags\"\n *ngIf=\"\n actionsObs.isReadOnlyProcess ||\n !actionsObs.hasEditPermissions ||\n actionsObs.isSystemProcess\n \"\n >\n <cds-tag\n *ngIf=\"actionsObs.isReadOnlyProcess || !actionsObs.hasEditPermissions\"\n type=\"blue\"\n >{{ 'processManagement.readOnly' | translate }}</cds-tag\n >\n\n <cds-tag *ngIf=\"actionsObs.isSystemProcess\" type=\"red\">{{\n 'processManagement.systemProcess' | translate\n }}</cds-tag>\n </div>\n\n <div class=\"page-header-actions__toggles\">\n <cds-tooltip\n align=\"bottom-left\"\n [autoAlign]=\"true\"\n [description]=\"'processManagement.draftTooltip' | translate\"\n >\n <cds-toggle\n size=\"sm\"\n [onText]=\"'processManagement.draft' | translate\"\n [offText]=\"'processManagement.draft' | translate\"\n [checked]=\"actionsObs.draft\"\n [disabled]=\"actionsObs.loading || !actionsObs.hasEditPermissions\"\n (checkedChange)=\"onProcessToggleChange('draft', $event)\"\n [attr.data-test-id]=\"testIds.draftToggle\"\n ></cds-toggle>\n </cds-tooltip>\n\n @if (actionsObs.context === 'case') {\n <cds-tooltip\n align=\"bottom-left\"\n [autoAlign]=\"true\"\n [description]=\"'processCaseConnection.processCreatesCaseTooltip' | translate\"\n >\n <cds-toggle\n size=\"sm\"\n [onText]=\"'processManagement.canInitializeDocument' | translate\"\n [offText]=\"'processManagement.canInitializeDocument' | translate\"\n [checked]=\"actionsObs.canInitializeDocument\"\n [disabled]=\"\n actionsObs.loading ||\n actionsObs.updatingProcessDefinitionCaseDefinition ||\n !actionsObs.hasEditPermissions\n \"\n (checkedChange)=\"onProcessToggleChange('canInitializeDocument', $event)\"\n [attr.data-test-id]=\"testIds.startsCaseToggle\"\n ></cds-toggle>\n </cds-tooltip>\n\n <cds-tooltip\n align=\"bottom-left\"\n [autoAlign]=\"true\"\n [description]=\"'processCaseConnection.startableWithinCaseTooltip' | translate\"\n >\n <cds-toggle\n size=\"sm\"\n [onText]=\"'processManagement.startableByUser' | translate\"\n [offText]=\"'processManagement.startableByUser' | translate\"\n [checked]=\"actionsObs.startableByUser\"\n [disabled]=\"\n actionsObs.loading ||\n actionsObs.updatingProcessDefinitionCaseDefinition ||\n !actionsObs.hasEditPermissions\n \"\n (checkedChange)=\"onProcessToggleChange('startableByUser', $event)\"\n [attr.data-test-id]=\"testIds.startableByUserToggle\"\n ></cds-toggle\n ></cds-tooltip>\n }\n </div>\n </div>\n\n <div class=\"page-header-actions__buttons\">\n <v-overflow-menu class=\"overflow-button\" placement=\"bottom-end\">\n <v-overflow-menu-trigger overflowTrigger></v-overflow-menu-trigger>\n <v-overflow-menu-option\n [disabled]=\"actionsObs.loading\"\n (selected)=\"export(actionsObs.isReadOnlyProcess)\"\n >{{ 'interface.export' | translate }}\n </v-overflow-menu-option>\n </v-overflow-menu>\n\n <button\n *ngIf=\"actionsObs.context === 'case'\"\n cdsButton=\"tertiary\"\n [size]=\"actionsObs.compactMode ? 'sm' : 'md'\"\n (click)=\"navigateBack(null)\"\n >\n {{ 'interface.back' | translate }}\n <svg class=\"cds--btn__icon\" cdsIcon=\"return\" size=\"16\"></svg>\n </button>\n\n <button\n cdsButton=\"secondary\"\n [size]=\"actionsObs.compactMode ? 'sm' : 'md'\"\n [disabled]=\"actionsObs.loading\"\n (click)=\"validateProcessDefinition(actionsObs.isReadOnlyProcess)\"\n >\n {{ 'processManagement.validate' | translate }}\n <svg class=\"cds--btn__icon\" cdsIcon=\"list--checked\" size=\"16\"></svg>\n </button>\n\n <button\n [disabled]=\"!actionsObs.changesPending\"\n cdsButton=\"primary\"\n (click)=\"\n !actionsObs.creatingNewProcess\n ? deployChanges(actionsObs.isReadOnlyProcess)\n : deployNewProcessDefinition()\n \"\n [size]=\"actionsObs.compactMode ? 'sm' : 'md'\"\n [attr.data-test-id]=\"testIds.deployButton\"\n >\n {{ 'processManagement.deploy' | translate }}\n\n <svg class=\"cds--btn__icon\" cdsIcon=\"deploy\" size=\"16\"></svg>\n </button>\n </div>\n </div>\n </ng-template>\n</ng-container>\n", styles: [":host{display:flex;flex-direction:column;gap:24px}.bpmn__container{position:relative;background-color:var(--cds-layer);width:100%}.bpmn__modeler{width:100%;height:100%;flex-direction:row;padding:1px;box-sizing:border-box;outline:1px solid var(--cds-border-subtle);outline-offset:-1px}.bpmn__modeler ::ng-deep .djs-container>svg{outline:none!important}.bpmn__modeler-canvas{width:100%;position:relative}.bpmn__modeler-panel{width:481px;padding-left:1px;box-shadow:inset 1px 0 0 0 var(--cds-border-subtle);box-sizing:border-box}.bpmn__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;align-items:center;gap:16px}.page-header-actions__left-container{display:flex;gap:16px;align-items:center}.page-header-actions__tags{display:flex;gap:8px;align-items:center}.page-header-actions__version-dropdown{width:150px}.page-header-actions__toggles{display:flex;gap:16px;align-items:center}.page-header-actions__toggles ::ng-deep cds-toggle{display:inline-flex;align-items:center}.page-header-actions__toggles ::ng-deep .cds--toggle__label-text{display:none}.page-header-actions__buttons{display:flex;gap:16px;align-items:center;flex-shrink:0}.valtimo-process-builder__header{display:flex;justify-content:space-between}.valtimo-process-builder__actions>*:not(:last-child){margin-right:8px}.validation-errors-list{position:absolute;top:8px;right:8px;z-index:10;width:320px;max-height:250px;overflow-y:auto;border:1px solid var(--cds-border-subtle);background-color:var(--cds-layer);border-radius:4px;box-shadow:0 2px 6px #00000026}.validation-errors-list details[open]>summary .validation-errors-list__arrow{transform:rotate(90deg)}.validation-errors-list__header{display:flex;align-items:center;justify-content:space-between;padding:12px 16px;font-size:14px;font-weight:600;color:var(--cds-support-error, #da1e28);cursor:pointer;list-style:none;-webkit-user-select:none;user-select:none}.validation-errors-list__header::-webkit-details-marker{display:none}.validation-errors-list__arrow{display:inline-flex;width:16px;height:16px;fill:currentColor;transition:transform .15s ease;flex-shrink:0}.validation-errors-list__items{display:flex;flex-direction:column;border-top:1px solid var(--cds-border-subtle)}.validation-errors-list__item{display:flex;align-items:flex-start;gap:10px;padding:10px 16px;border:none;border-bottom:1px solid var(--cds-border-subtle);border-left:3px solid var(--cds-support-error, #da1e28);background-color:var(--cds-notification-error-background, #fff1f1);text-align:left;cursor:pointer;font-family:inherit}.validation-errors-list__item.warning{background-color:var(--cds-notification-warning-background, #fdf6dd);border-left-color:var(--cds-support-warning, #f1c21b)}.validation-errors-list__item:last-child{border-bottom:none}.validation-errors-list__item:hover{filter:brightness(.97)}.validation-errors-list__icon{display:flex;align-items:center;justify-content:center;width:18px;height:18px;min-width:18px;margin-top:1px;border-radius:50%;background-color:var(--cds-support-error, #da1e28);color:var(--cds-text-on-color, #ffffff);font-size:12px;font-weight:700;line-height:0}.validation-errors-list__icon.warning{background-color:var(--cds-support-warning, #f1c21b);color:var(--cds-text-primary, #161616)}.validation-errors-list__details{display:flex;flex-direction:column;gap:2px}.validation-errors-list__element{font-size:13px;font-weight:600;color:var(--cds-text-primary)}.validation-errors-list__reason{font-size:13px;color:var(--cds-text-primary)}::ng-deep .highlight-overlay-error:not(.djs-connection) .djs-visual>:nth-child(1){stroke:var(--cds-support-error, #da1e28)!important}::ng-deep .highlight-overlay-warning:not(.djs-connection) .djs-visual>:nth-child(1){stroke:var(--cds-support-warning, #f1c21b)!important}::ng-deep .djs-overlay-validation-error{overflow:visible!important;pointer-events:all!important}::ng-deep .validation-error-overlay{position:relative;cursor:pointer;pointer-events:all}::ng-deep .validation-error-overlay__icon{display:flex;align-items:center;justify-content:center;width:22px;height:22px;border-radius:50%;background-color:var(--cds-support-error, #da1e28);color:var(--cds-text-on-color, #ffffff);font-size:14px;font-weight:700;line-height:0}::ng-deep .validation-error-overlay__text{display:none;position:absolute;bottom:100%;left:50%;transform:translate(-50%);margin-bottom:4px;border:1px solid var(--cds-support-error, #da1e28);color:var(--cds-support-error, #da1e28);background-color:var(--cds-layer, #ffffff);padding:4px 8px;border-radius:2px;font-size:14px;white-space:nowrap;max-width:350px;overflow:hidden;text-overflow:ellipsis;z-index:10}::ng-deep .validation-error-overlay:hover ::ng-deep .validation-error-overlay__text,::ng-deep .validation-error-overlay--active ::ng-deep .validation-error-overlay__text{display:block}::ng-deep .validation-warning-overlay{position:relative;cursor:pointer;pointer-events:all}::ng-deep .validation-warning-overlay__icon{display:flex;align-items:center;justify-content:center;width:22px;height:22px;border-radius:50%;background-color:var(--cds-support-warning, #f1c21b);color:var(--cds-text-primary, #161616);font-size:14px;font-weight:700;line-height:0}::ng-deep .validation-warning-overlay__text{display:none;position:absolute;bottom:100%;left:50%;transform:translate(-50%);margin-bottom:4px;border:1px solid var(--cds-support-warning, #f1c21b);color:var(--cds-text-primary, #161616);background-color:var(--cds-layer, #ffffff);padding:4px 8px;border-radius:2px;font-size:14px;white-space:nowrap;max-width:350px;overflow:hidden;text-overflow:ellipsis;z-index:10}::ng-deep .validation-warning-overlay:hover ::ng-deep .validation-warning-overlay__text,::ng-deep .validation-warning-overlay--active ::ng-deep .validation-warning-overlay__text{display:block}::ng-deep .validation-errors-panel{padding:8px 12px;display:flex;flex-direction:column;gap:8px}::ng-deep .validation-errors-panel__item{display:flex;align-items:flex-start;gap:8px;padding:8px 12px;background-color:var(--cds-notification-error-background, #fff1f1);border-left:3px solid var(--cds-support-error, #da1e28)}::ng-deep .validation-errors-panel__item.warning{background-color:var(--cds-notification-warning-background, #fdf6dd);border-left-color:var(--cds-support-warning, #f1c21b)}::ng-deep .validation-errors-panel__icon{display:flex;align-items:center;justify-content:center;width:18px;height:18px;min-width:18px;border-radius:50%;background-color:var(--cds-support-error, #da1e28);color:var(--cds-text-on-color, #ffffff);font-size:12px;font-weight:700;line-height:0}::ng-deep .validation-errors-panel__icon.warning{background-color:var(--cds-support-warning, #f1c21b);color:var(--cds-text-primary, #161616)}::ng-deep .validation-errors-panel__reason{color:var(--cds-text-primary, #161616);font-size:13px;line-height:18px}::ng-deep .process-link-properties-panel{padding:8px 12px 16px;width:100%;display:flex;flex-direction:column;gap:16px}::ng-deep .process-link-properties-panel__buttons,::ng-deep .process-link-properties-panel__header{width:100%;display:flex;gap:16px}::ng-deep .process-link-properties-panel__header{align-items:flex-start;justify-content:space-between;border-bottom:1px solid var(--cds-border-subtle-00);padding-bottom:8px;padding-left:8px;padding-right:8px}::ng-deep .process-link-properties-panel__title{color:var(--cds-text-secondary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:200px;margin:auto 0}::ng-deep .process-link-properties-panel__title-container{display:flex;flex-direction:column;gap:4px}::ng-deep .process-link-properties-panel__title-container :last-child{color:var(--cds-text-helper);font-style:italic}::ng-deep .process-link-properties-panel .cds--tag{margin:0}::ng-deep .process-link-properties-panel .cds--btn{flex-shrink:1;width:100%;display:flex;align-items:center}\n/*!\n * Copyright 2015-2025 Ritense BV, the Netherlands.\n *\n * Licensed under EUPL, Version 1.2 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i6.AsyncPipe, name: "async" }, { kind: "directive", type: FitPageDirective, selector: "[fitPage]", inputs: ["spaceAdjustment", "fitPageDisabled", "disableOverflow", "bottomMargin"] }, { kind: "ngmodule", type: LoadingModule }, { kind: "directive", type: RenderInPageHeaderDirective, selector: "[renderInPageHeader]", inputs: ["fullWidth"] }, { kind: "ngmodule", type: DropdownModule }, { kind: "component", type: i2$2.Dropdown, selector: "cds-dropdown, ibm-dropdown", inputs: ["id", "label", "hideLabel", "helperText", "placeholder", "displayValue", "clearText", "size", "type", "theme", "disabled", "readonly", "skeleton", "inline", "disableArrowKeys", "invalid", "invalidText", "warn", "warnText", "appendInline", "scrollableContainer", "itemValueKey", "selectionFeedback", "menuButtonLabel", "selectedLabel", "dropUp", "fluid"], outputs: ["selected", "onClose", "close"] }, { kind: "component", type: i2$2.DropdownList, selector: "cds-dropdown-list, ibm-dropdown-list", inputs: ["ariaLabel", "items", "listTpl", "type", "showTitles"], outputs: ["select", "scroll", "blurIntent"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: SelectModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2$2.Button, selector: "[cdsButton], [ibmButton]", inputs: ["ibmButton", "cdsButton", "size", "skeleton", "iconOnly", "isExpressive"] }, { kind: "ngmodule", type: IconModule }, { kind: "directive", type: i2$2.IconDirective, selector: "[cdsIcon], [ibmIcon]", inputs: ["ibmIcon", "cdsIcon", "size", "title", "ariaLabel", "ariaLabelledBy", "ariaHidden", "isFocusable"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i9.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: TagModule }, { kind: "component", type: i2$2.Tag, selector: "cds-tag, ibm-tag", inputs: ["type", "size", "class", "skeleton"] }, { kind: "ngmodule", type: ProcessLinkModule }, { kind: "component", type: i5.ProcessLinkModalComponent, selector: "valtimo-process-link-modal" }, { kind: "component", type: OverflowMenuComponent, selector: "v-overflow-menu", inputs: ["open", "placement", "menuWidth", "offsetX", "offsetY", "closeOnSelect", "useHostAsReference", "portalToBody"], outputs: ["openChange"] }, { kind: "component", type: OverflowMenuOptionComponent, selector: "v-overflow-menu-option", inputs: ["disabled", "type", "testId", "optionId"], outputs: ["selected"] }, { kind: "component", type: OverflowMenuTriggerComponent, selector: "v-overflow-menu-trigger", inputs: ["compact"] }, { kind: "ngmodule", type: ToggleModule }, { kind: "component", type: i2$2.Toggle, selector: "cds-toggle, ibm-toggle", inputs: ["offText", "onText", "label", "size", "hideLabel", "ariaLabel", "skeleton"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "component", type: i2$2.Tooltip, selector: "cds-tooltip, ibm-tooltip", inputs: ["id", "enterDelayMs", "leaveDelayMs", "disabled", "description", "templateContext"] }, { kind: "ngmodule", type: ConfirmationModalModule }, { kind: "component", type: i1$1.ConfirmationModalComponent, selector: "valtimo-confirmation-modal", inputs: ["titleTranslationKey", "title", "content", "contentTranslationKey", "confirmButtonText", "confirmButtonTextTranslationKey", "confirmButtonType", "showOptionalButton", "optionalButtonText", "optionalButtonTextTranslationKey", "optionalButtonType", "cancelButtonText", "cancelButtonTextTranslationKey", "cancelButtonType", "showModalSubject$", "outputOnConfirm", "outputOnOptional", "spacerAfterCancelButton"], outputs: ["confirmEvent", "optionalEvent", "cancelEvent"] }] }); }
|
|
1561
1923
|
}
|
|
1562
1924
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: ProcessManagementBuilderComponent, decorators: [{
|
|
1563
1925
|
type: Component,
|
|
@@ -1580,12 +1942,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImpo
|
|
|
1580
1942
|
OverflowMenuTriggerComponent,
|
|
1581
1943
|
ToggleModule,
|
|
1582
1944
|
TooltipModule,
|
|
1945
|
+
ConfirmationModalModule,
|
|
1583
1946
|
], providers: [
|
|
1584
1947
|
ProcessManagementEditorService,
|
|
1585
1948
|
ProcessLinkStateService,
|
|
1586
1949
|
ProcessLinkStepService,
|
|
1587
1950
|
ProcessLinkButtonService,
|
|
1588
|
-
], template: "<!--\n ~ Copyright 2015-2025 Ritense BV, the Netherlands.\n ~\n ~ Licensed under EUPL, Version 1.2 (the \"License\");\n ~ you may not use this file except in compliance with the License.\n ~ You may obtain a copy of the License at\n ~\n ~ https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12\n ~\n ~ Unless required by applicable law or agreed to in writing, software\n ~ distributed under the License is distributed on an \"AS IS\" basis,\n ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ~ See the License for the specific language governing permissions and\n ~ limitations under the License.\n -->\n\n<div\n fitPage\n [spaceAdjustment]=\"$spaceAdjustment()\"\n [disableOverflow]=\"true\"\n *ngIf=\"{\n processDefinitionVersions: processDefinitionVersions$ | async,\n selectedProcessDefinitionXml: selectedProcessDefinitionXml$ | async,\n loading: loading$ | async,\n isReadOnlyProcess: isReadOnlyProcess$ | async,\n hasEditPermissions: hasEditPermissions$ | async,\n } as obs\"\n data-carbon-theme=\"g10\"\n class=\"bpmn__container\"\n>\n <div\n class=\"bpmn__modeler\"\n [style.display]=\"obs.isReadOnlyProcess || !obs.hasEditPermissions ? 'none' : 'flex'\"\n >\n <div class=\"bpmn__modeler-canvas\" #modeler></div>\n\n <div class=\"bpmn__modeler-panel\" #modelerPanel></div>\n </div>\n\n <div\n class=\"bpmn__modeler\"\n [style.display]=\"obs.isReadOnlyProcess || !obs.hasEditPermissions ? 'flex' : 'none'\"\n >\n <div class=\"bpmn__modeler-canvas\" #viewer></div>\n\n <div class=\"bpmn__modeler-panel\" #viewerPanel></div>\n </div>\n</div>\n\n<valtimo-process-link-modal></valtimo-process-link-modal>\n\n<ng-container renderInPageHeader [fullWidth]=\"true\">\n <ng-template>\n <div\n class=\"page-header-actions\"\n *ngIf=\"{\n processDefinitionVersionsListItems: processDefinitionVersionsListItems$ | async,\n loading: loading$ | async,\n changesPending: changesPending$ | async,\n isReadOnlyProcess: isReadOnlyProcess$ | async,\n isSystemProcess: isSystemProcess$ | async,\n compactMode: compactMode$ | async,\n creatingNewProcess: creatingNewProcess$ | async,\n context: context$ | async,\n hasEditPermissions: hasEditPermissions$ | async,\n canInitializeDocument: canInitializeDocument$ | async,\n startableByUser: startableByUser$ | async,\n updatingProcessDefinitionCaseDefinition: updatingProcessDefinitionCaseDefinition$ | async,\n } as actionsObs\"\n >\n <div class=\"page-header-actions__left-container\">\n <cds-dropdown\n *ngIf=\"!actionsObs.creatingNewProcess && actionsObs?.context === 'independent'\"\n class=\"page-header-actions__version-dropdown\"\n (selected)=\"selectedVersionChange($event)\"\n [disabled]=\"\n actionsObs.loading ||\n (actionsObs.processDefinitionVersionsListItems || []).length === 0 ||\n (actionsObs.processDefinitionVersionsListItems || []).length === 1\n \"\n [size]=\"actionsObs.compactMode ? 'sm' : 'md'\"\n >\n <cds-dropdown-list\n [items]=\"actionsObs.processDefinitionVersionsListItems || []\"\n ></cds-dropdown-list>\n </cds-dropdown>\n\n <div class=\"page-header-actions__tags\">\n <cds-tag\n *ngIf=\"actionsObs.isReadOnlyProcess || !actionsObs.hasEditPermissions\"\n type=\"blue\"\n >{{ 'processManagement.readOnly' | translate }}</cds-tag\n >\n\n <cds-tag *ngIf=\"actionsObs.isSystemProcess\" type=\"red\">{{\n 'processManagement.systemProcess' | translate\n }}</cds-tag>\n </div>\n </div>\n\n <div class=\"page-header-actions__buttons\">\n @if (actionsObs.context === 'case') {\n <cds-tooltip\n [description]=\"'processCaseConnection.processCreatesCaseTooltip' | translate\"\n >\n <cds-toggle\n [onText]=\"'processManagement.canInitializeDocument' | translate\"\n [offText]=\"'processManagement.canInitializeDocument' | translate\"\n [checked]=\"actionsObs.canInitializeDocument\"\n [disabled]=\"\n actionsObs.loading ||\n actionsObs.updatingProcessDefinitionCaseDefinition ||\n !actionsObs.hasEditPermissions\n \"\n (checkedChange)=\"onProcessToggleChange('canInitializeDocument', $event)\"\n [attr.data-test-id]=\"testIds.startsCaseToggle\"\n ></cds-toggle>\n </cds-tooltip>\n\n <cds-tooltip\n [description]=\"'processCaseConnection.startableWithinCaseTooltip' | translate\"\n >\n <cds-toggle\n [onText]=\"'processManagement.startableByUser' | translate\"\n [offText]=\"'processManagement.startableByUser' | translate\"\n [checked]=\"actionsObs.startableByUser\"\n [disabled]=\"\n actionsObs.loading ||\n actionsObs.updatingProcessDefinitionCaseDefinition ||\n !actionsObs.hasEditPermissions\n \"\n (checkedChange)=\"onProcessToggleChange('startableByUser', $event)\"\n [attr.data-test-id]=\"testIds.startableByUserToggle\"\n ></cds-toggle\n ></cds-tooltip>\n }\n\n <button\n *ngIf=\"actionsObs.context === 'case'\"\n cdsButton=\"secondary\"\n [size]=\"actionsObs.compactMode ? 'sm' : 'md'\"\n (click)=\"navigateBack(null)\"\n >\n <svg class=\"cds--btn__icon\" cdsIcon=\"arrow--left\" size=\"16\"></svg>\n\n <span>{{ 'interface.back' | translate }}</span>\n </button>\n\n <button\n [disabled]=\"!actionsObs.changesPending\"\n cdsButton=\"primary\"\n (click)=\"\n !actionsObs.creatingNewProcess\n ? deployChanges(actionsObs.isReadOnlyProcess)\n : deployNewProcessDefinition()\n \"\n [size]=\"actionsObs.compactMode ? 'sm' : 'md'\"\n [attr.data-test-id]=\"testIds.deployButton\"\n >\n {{ 'processManagement.deploy' | translate }}\n\n <svg class=\"cds--btn__icon\" cdsIcon=\"deploy\" size=\"16\"></svg>\n </button>\n\n <v-overflow-menu class=\"overflow-button\" placement=\"bottom-end\">\n <v-overflow-menu-trigger overflowTrigger></v-overflow-menu-trigger>\n <v-overflow-menu-option\n [disabled]=\"actionsObs.loading\"\n (selected)=\"export(actionsObs.isReadOnlyProcess)\"\n >{{ 'interface.export' | translate }}\n </v-overflow-menu-option>\n </v-overflow-menu>\n </div>\n </div>\n </ng-template>\n</ng-container>\n", styles: [":host{display:flex;flex-direction:column;gap:24px}.bpmn__container{position:relative;background-color:var(--cds-layer);width:100%}.bpmn__modeler{width:100%;height:100%;flex-direction:row;padding:1px;box-sizing:border-box;outline:1px solid var(--cds-border-subtle);outline-offset:-1px}.bpmn__modeler ::ng-deep .djs-container>svg{outline:none!important}.bpmn__modeler-canvas{width:100%}.bpmn__modeler-panel{width:481px;padding-left:1px;box-shadow:inset 1px 0 0 0 var(--cds-border-subtle);box-sizing:border-box}.bpmn__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}.page-header-actions__left-container{display:flex;gap:24px;align-items:flex-end}.page-header-actions__tags{display:flex;gap:8px;align-items:flex-end}.page-header-actions__version-dropdown{width:150px}.page-header-actions__buttons{display:flex;gap:16px;align-items:center}.page-header-actions__buttons cds-toggle{height:24px}.page-header-actions__buttons ::ng-deep .cds--toggle__label-text{display:none}.valtimo-process-builder__header{display:flex;justify-content:space-between}.valtimo-process-builder__actions>*:not(:last-child){margin-right:8px}::ng-deep .process-link-properties-panel{padding:8px 12px 16px;width:100%;display:flex;flex-direction:column;gap:16px}::ng-deep .process-link-properties-panel__buttons,::ng-deep .process-link-properties-panel__header{width:100%;display:flex;gap:16px}::ng-deep .process-link-properties-panel__header{align-items:flex-start;justify-content:space-between;border-bottom:1px solid var(--cds-border-subtle-00);padding-bottom:8px;padding-left:8px;padding-right:8px}::ng-deep .process-link-properties-panel__title{color:var(--cds-text-secondary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:200px;margin:auto 0}::ng-deep .process-link-properties-panel__title-container{display:flex;flex-direction:column;gap:4px}::ng-deep .process-link-properties-panel__title-container :last-child{color:var(--cds-text-helper);font-style:italic}::ng-deep .process-link-properties-panel .cds--tag{margin:0}::ng-deep .process-link-properties-panel .cds--btn{flex-shrink:1;width:100%;display:flex;align-items:center}\n/*!\n * Copyright 2015-2025 Ritense BV, the Netherlands.\n *\n * Licensed under EUPL, Version 1.2 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n"] }]
|
|
1951
|
+
], template: "<!--\n ~ Copyright 2015-2026 Ritense BV, the Netherlands.\n ~\n ~ Licensed under EUPL, Version 1.2 (the \"License\");\n ~ you may not use this file except in compliance with the License.\n ~ You may obtain a copy of the License at\n ~\n ~ https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12\n ~\n ~ Unless required by applicable law or agreed to in writing, software\n ~ distributed under the License is distributed on an \"AS IS\" basis,\n ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ~ See the License for the specific language governing permissions and\n ~ limitations under the License.\n -->\n\n<div\n fitPage\n [disableOverflow]=\"true\"\n *ngIf=\"{\n processDefinitionVersions: processDefinitionVersions$ | async,\n selectedProcessDefinitionXml: selectedProcessDefinitionXml$ | async,\n loading: loading$ | async,\n isReadOnlyProcess: isReadOnlyProcess$ | async,\n hasEditPermissions: hasEditPermissions$ | async,\n } as obs\"\n data-carbon-theme=\"g10\"\n class=\"bpmn__container\"\n>\n <div\n class=\"bpmn__modeler\"\n [style.display]=\"obs.isReadOnlyProcess || !obs.hasEditPermissions ? 'none' : 'flex'\"\n >\n <div class=\"bpmn__modeler-canvas\" #modeler>\n <div\n class=\"validation-errors-list\"\n *ngIf=\"validationErrors$ | async as validationErrors\"\n [style.display]=\"validationErrors.length > 0 ? '' : 'none'\"\n >\n <details open>\n <summary class=\"validation-errors-list__header\">\n <span>{{\n 'processManagement.validationErrorsCount'\n | translate: {count: validationErrors.length}\n }}</span>\n <svg\n class=\"validation-errors-list__arrow\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n >\n <path\n fill-rule=\"evenodd\"\n d=\"m11.657 8-4.95 4.95a1 1 0 0 1-1.414-1.414L8.828 8 5.293 4.464A1 1 0 1 1 6.707 3.05L11.657 8Z\"\n />\n </svg>\n </summary>\n\n <div class=\"validation-errors-list__items\">\n <button\n *ngFor=\"let error of validationErrors\"\n class=\"validation-errors-list__item\"\n [class.warning]=\"error.severity === 'WARNING'\"\n (click)=\"onValidationErrorClick(error.elementId)\"\n >\n <span\n class=\"validation-errors-list__icon\"\n [class.warning]=\"error.severity === 'WARNING'\"\n >{{ error.severity === 'WARNING' ? '!' : '!' }}</span\n >\n\n <span class=\"validation-errors-list__details\">\n <span class=\"validation-errors-list__element\">{{\n error.elementName || error.elementId\n }}</span>\n\n <span\n class=\"validation-errors-list__reason\"\n [class.warning]=\"error.severity === 'WARNING'\"\n >{{ getValidationErrorMessage(error) }}</span\n >\n </span>\n </button>\n </div>\n </details>\n </div>\n </div>\n\n <div class=\"bpmn__modeler-panel\" #modelerPanel></div>\n </div>\n\n <div\n class=\"bpmn__modeler\"\n [style.display]=\"obs.isReadOnlyProcess || !obs.hasEditPermissions ? 'flex' : 'none'\"\n >\n <div class=\"bpmn__modeler-canvas\" #viewer></div>\n\n <div class=\"bpmn__modeler-panel\" #viewerPanel></div>\n </div>\n</div>\n\n<valtimo-process-link-modal></valtimo-process-link-modal>\n\n<valtimo-confirmation-modal\n [showModalSubject$]=\"showWarningConfirmationModal$\"\n [titleTranslationKey]=\"'processManagement.warningConfirmation.title'\"\n [contentTranslationKey]=\"'processManagement.warningConfirmation.content'\"\n [confirmButtonTextTranslationKey]=\"'processManagement.warningConfirmation.confirm'\"\n [cancelButtonTextTranslationKey]=\"'interface.cancel'\"\n (confirmEvent)=\"onWarningConfirmationConfirm()\"\n (cancelEvent)=\"onWarningConfirmationCancel()\"\n></valtimo-confirmation-modal>\n\n<ng-container renderInPageHeader [fullWidth]=\"true\">\n <ng-template>\n <div\n class=\"page-header-actions\"\n *ngIf=\"{\n processDefinitionVersionsListItems: processDefinitionVersionsListItems$ | async,\n loading: loading$ | async,\n changesPending: changesPending$ | async,\n isReadOnlyProcess: isReadOnlyProcess$ | async,\n isSystemProcess: isSystemProcess$ | async,\n compactMode: compactMode$ | async,\n creatingNewProcess: creatingNewProcess$ | async,\n context: context$ | async,\n hasEditPermissions: hasEditPermissions$ | async,\n draft: draft$ | async,\n canInitializeDocument: canInitializeDocument$ | async,\n startableByUser: startableByUser$ | async,\n updatingProcessDefinitionCaseDefinition: updatingProcessDefinitionCaseDefinition$ | async,\n } as actionsObs\"\n >\n <div class=\"page-header-actions__left-container\">\n <cds-dropdown\n *ngIf=\"!actionsObs.creatingNewProcess && actionsObs?.context === 'independent'\"\n class=\"page-header-actions__version-dropdown\"\n (selected)=\"selectedVersionChange($event)\"\n [disabled]=\"\n actionsObs.loading ||\n (actionsObs.processDefinitionVersionsListItems || []).length === 0 ||\n (actionsObs.processDefinitionVersionsListItems || []).length === 1\n \"\n [size]=\"actionsObs.compactMode ? 'sm' : 'md'\"\n >\n <cds-dropdown-list\n [items]=\"actionsObs.processDefinitionVersionsListItems || []\"\n ></cds-dropdown-list>\n </cds-dropdown>\n\n <div\n class=\"page-header-actions__tags\"\n *ngIf=\"\n actionsObs.isReadOnlyProcess ||\n !actionsObs.hasEditPermissions ||\n actionsObs.isSystemProcess\n \"\n >\n <cds-tag\n *ngIf=\"actionsObs.isReadOnlyProcess || !actionsObs.hasEditPermissions\"\n type=\"blue\"\n >{{ 'processManagement.readOnly' | translate }}</cds-tag\n >\n\n <cds-tag *ngIf=\"actionsObs.isSystemProcess\" type=\"red\">{{\n 'processManagement.systemProcess' | translate\n }}</cds-tag>\n </div>\n\n <div class=\"page-header-actions__toggles\">\n <cds-tooltip\n align=\"bottom-left\"\n [autoAlign]=\"true\"\n [description]=\"'processManagement.draftTooltip' | translate\"\n >\n <cds-toggle\n size=\"sm\"\n [onText]=\"'processManagement.draft' | translate\"\n [offText]=\"'processManagement.draft' | translate\"\n [checked]=\"actionsObs.draft\"\n [disabled]=\"actionsObs.loading || !actionsObs.hasEditPermissions\"\n (checkedChange)=\"onProcessToggleChange('draft', $event)\"\n [attr.data-test-id]=\"testIds.draftToggle\"\n ></cds-toggle>\n </cds-tooltip>\n\n @if (actionsObs.context === 'case') {\n <cds-tooltip\n align=\"bottom-left\"\n [autoAlign]=\"true\"\n [description]=\"'processCaseConnection.processCreatesCaseTooltip' | translate\"\n >\n <cds-toggle\n size=\"sm\"\n [onText]=\"'processManagement.canInitializeDocument' | translate\"\n [offText]=\"'processManagement.canInitializeDocument' | translate\"\n [checked]=\"actionsObs.canInitializeDocument\"\n [disabled]=\"\n actionsObs.loading ||\n actionsObs.updatingProcessDefinitionCaseDefinition ||\n !actionsObs.hasEditPermissions\n \"\n (checkedChange)=\"onProcessToggleChange('canInitializeDocument', $event)\"\n [attr.data-test-id]=\"testIds.startsCaseToggle\"\n ></cds-toggle>\n </cds-tooltip>\n\n <cds-tooltip\n align=\"bottom-left\"\n [autoAlign]=\"true\"\n [description]=\"'processCaseConnection.startableWithinCaseTooltip' | translate\"\n >\n <cds-toggle\n size=\"sm\"\n [onText]=\"'processManagement.startableByUser' | translate\"\n [offText]=\"'processManagement.startableByUser' | translate\"\n [checked]=\"actionsObs.startableByUser\"\n [disabled]=\"\n actionsObs.loading ||\n actionsObs.updatingProcessDefinitionCaseDefinition ||\n !actionsObs.hasEditPermissions\n \"\n (checkedChange)=\"onProcessToggleChange('startableByUser', $event)\"\n [attr.data-test-id]=\"testIds.startableByUserToggle\"\n ></cds-toggle\n ></cds-tooltip>\n }\n </div>\n </div>\n\n <div class=\"page-header-actions__buttons\">\n <v-overflow-menu class=\"overflow-button\" placement=\"bottom-end\">\n <v-overflow-menu-trigger overflowTrigger></v-overflow-menu-trigger>\n <v-overflow-menu-option\n [disabled]=\"actionsObs.loading\"\n (selected)=\"export(actionsObs.isReadOnlyProcess)\"\n >{{ 'interface.export' | translate }}\n </v-overflow-menu-option>\n </v-overflow-menu>\n\n <button\n *ngIf=\"actionsObs.context === 'case'\"\n cdsButton=\"tertiary\"\n [size]=\"actionsObs.compactMode ? 'sm' : 'md'\"\n (click)=\"navigateBack(null)\"\n >\n {{ 'interface.back' | translate }}\n <svg class=\"cds--btn__icon\" cdsIcon=\"return\" size=\"16\"></svg>\n </button>\n\n <button\n cdsButton=\"secondary\"\n [size]=\"actionsObs.compactMode ? 'sm' : 'md'\"\n [disabled]=\"actionsObs.loading\"\n (click)=\"validateProcessDefinition(actionsObs.isReadOnlyProcess)\"\n >\n {{ 'processManagement.validate' | translate }}\n <svg class=\"cds--btn__icon\" cdsIcon=\"list--checked\" size=\"16\"></svg>\n </button>\n\n <button\n [disabled]=\"!actionsObs.changesPending\"\n cdsButton=\"primary\"\n (click)=\"\n !actionsObs.creatingNewProcess\n ? deployChanges(actionsObs.isReadOnlyProcess)\n : deployNewProcessDefinition()\n \"\n [size]=\"actionsObs.compactMode ? 'sm' : 'md'\"\n [attr.data-test-id]=\"testIds.deployButton\"\n >\n {{ 'processManagement.deploy' | translate }}\n\n <svg class=\"cds--btn__icon\" cdsIcon=\"deploy\" size=\"16\"></svg>\n </button>\n </div>\n </div>\n </ng-template>\n</ng-container>\n", styles: [":host{display:flex;flex-direction:column;gap:24px}.bpmn__container{position:relative;background-color:var(--cds-layer);width:100%}.bpmn__modeler{width:100%;height:100%;flex-direction:row;padding:1px;box-sizing:border-box;outline:1px solid var(--cds-border-subtle);outline-offset:-1px}.bpmn__modeler ::ng-deep .djs-container>svg{outline:none!important}.bpmn__modeler-canvas{width:100%;position:relative}.bpmn__modeler-panel{width:481px;padding-left:1px;box-shadow:inset 1px 0 0 0 var(--cds-border-subtle);box-sizing:border-box}.bpmn__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;align-items:center;gap:16px}.page-header-actions__left-container{display:flex;gap:16px;align-items:center}.page-header-actions__tags{display:flex;gap:8px;align-items:center}.page-header-actions__version-dropdown{width:150px}.page-header-actions__toggles{display:flex;gap:16px;align-items:center}.page-header-actions__toggles ::ng-deep cds-toggle{display:inline-flex;align-items:center}.page-header-actions__toggles ::ng-deep .cds--toggle__label-text{display:none}.page-header-actions__buttons{display:flex;gap:16px;align-items:center;flex-shrink:0}.valtimo-process-builder__header{display:flex;justify-content:space-between}.valtimo-process-builder__actions>*:not(:last-child){margin-right:8px}.validation-errors-list{position:absolute;top:8px;right:8px;z-index:10;width:320px;max-height:250px;overflow-y:auto;border:1px solid var(--cds-border-subtle);background-color:var(--cds-layer);border-radius:4px;box-shadow:0 2px 6px #00000026}.validation-errors-list details[open]>summary .validation-errors-list__arrow{transform:rotate(90deg)}.validation-errors-list__header{display:flex;align-items:center;justify-content:space-between;padding:12px 16px;font-size:14px;font-weight:600;color:var(--cds-support-error, #da1e28);cursor:pointer;list-style:none;-webkit-user-select:none;user-select:none}.validation-errors-list__header::-webkit-details-marker{display:none}.validation-errors-list__arrow{display:inline-flex;width:16px;height:16px;fill:currentColor;transition:transform .15s ease;flex-shrink:0}.validation-errors-list__items{display:flex;flex-direction:column;border-top:1px solid var(--cds-border-subtle)}.validation-errors-list__item{display:flex;align-items:flex-start;gap:10px;padding:10px 16px;border:none;border-bottom:1px solid var(--cds-border-subtle);border-left:3px solid var(--cds-support-error, #da1e28);background-color:var(--cds-notification-error-background, #fff1f1);text-align:left;cursor:pointer;font-family:inherit}.validation-errors-list__item.warning{background-color:var(--cds-notification-warning-background, #fdf6dd);border-left-color:var(--cds-support-warning, #f1c21b)}.validation-errors-list__item:last-child{border-bottom:none}.validation-errors-list__item:hover{filter:brightness(.97)}.validation-errors-list__icon{display:flex;align-items:center;justify-content:center;width:18px;height:18px;min-width:18px;margin-top:1px;border-radius:50%;background-color:var(--cds-support-error, #da1e28);color:var(--cds-text-on-color, #ffffff);font-size:12px;font-weight:700;line-height:0}.validation-errors-list__icon.warning{background-color:var(--cds-support-warning, #f1c21b);color:var(--cds-text-primary, #161616)}.validation-errors-list__details{display:flex;flex-direction:column;gap:2px}.validation-errors-list__element{font-size:13px;font-weight:600;color:var(--cds-text-primary)}.validation-errors-list__reason{font-size:13px;color:var(--cds-text-primary)}::ng-deep .highlight-overlay-error:not(.djs-connection) .djs-visual>:nth-child(1){stroke:var(--cds-support-error, #da1e28)!important}::ng-deep .highlight-overlay-warning:not(.djs-connection) .djs-visual>:nth-child(1){stroke:var(--cds-support-warning, #f1c21b)!important}::ng-deep .djs-overlay-validation-error{overflow:visible!important;pointer-events:all!important}::ng-deep .validation-error-overlay{position:relative;cursor:pointer;pointer-events:all}::ng-deep .validation-error-overlay__icon{display:flex;align-items:center;justify-content:center;width:22px;height:22px;border-radius:50%;background-color:var(--cds-support-error, #da1e28);color:var(--cds-text-on-color, #ffffff);font-size:14px;font-weight:700;line-height:0}::ng-deep .validation-error-overlay__text{display:none;position:absolute;bottom:100%;left:50%;transform:translate(-50%);margin-bottom:4px;border:1px solid var(--cds-support-error, #da1e28);color:var(--cds-support-error, #da1e28);background-color:var(--cds-layer, #ffffff);padding:4px 8px;border-radius:2px;font-size:14px;white-space:nowrap;max-width:350px;overflow:hidden;text-overflow:ellipsis;z-index:10}::ng-deep .validation-error-overlay:hover ::ng-deep .validation-error-overlay__text,::ng-deep .validation-error-overlay--active ::ng-deep .validation-error-overlay__text{display:block}::ng-deep .validation-warning-overlay{position:relative;cursor:pointer;pointer-events:all}::ng-deep .validation-warning-overlay__icon{display:flex;align-items:center;justify-content:center;width:22px;height:22px;border-radius:50%;background-color:var(--cds-support-warning, #f1c21b);color:var(--cds-text-primary, #161616);font-size:14px;font-weight:700;line-height:0}::ng-deep .validation-warning-overlay__text{display:none;position:absolute;bottom:100%;left:50%;transform:translate(-50%);margin-bottom:4px;border:1px solid var(--cds-support-warning, #f1c21b);color:var(--cds-text-primary, #161616);background-color:var(--cds-layer, #ffffff);padding:4px 8px;border-radius:2px;font-size:14px;white-space:nowrap;max-width:350px;overflow:hidden;text-overflow:ellipsis;z-index:10}::ng-deep .validation-warning-overlay:hover ::ng-deep .validation-warning-overlay__text,::ng-deep .validation-warning-overlay--active ::ng-deep .validation-warning-overlay__text{display:block}::ng-deep .validation-errors-panel{padding:8px 12px;display:flex;flex-direction:column;gap:8px}::ng-deep .validation-errors-panel__item{display:flex;align-items:flex-start;gap:8px;padding:8px 12px;background-color:var(--cds-notification-error-background, #fff1f1);border-left:3px solid var(--cds-support-error, #da1e28)}::ng-deep .validation-errors-panel__item.warning{background-color:var(--cds-notification-warning-background, #fdf6dd);border-left-color:var(--cds-support-warning, #f1c21b)}::ng-deep .validation-errors-panel__icon{display:flex;align-items:center;justify-content:center;width:18px;height:18px;min-width:18px;border-radius:50%;background-color:var(--cds-support-error, #da1e28);color:var(--cds-text-on-color, #ffffff);font-size:12px;font-weight:700;line-height:0}::ng-deep .validation-errors-panel__icon.warning{background-color:var(--cds-support-warning, #f1c21b);color:var(--cds-text-primary, #161616)}::ng-deep .validation-errors-panel__reason{color:var(--cds-text-primary, #161616);font-size:13px;line-height:18px}::ng-deep .process-link-properties-panel{padding:8px 12px 16px;width:100%;display:flex;flex-direction:column;gap:16px}::ng-deep .process-link-properties-panel__buttons,::ng-deep .process-link-properties-panel__header{width:100%;display:flex;gap:16px}::ng-deep .process-link-properties-panel__header{align-items:flex-start;justify-content:space-between;border-bottom:1px solid var(--cds-border-subtle-00);padding-bottom:8px;padding-left:8px;padding-right:8px}::ng-deep .process-link-properties-panel__title{color:var(--cds-text-secondary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:200px;margin:auto 0}::ng-deep .process-link-properties-panel__title-container{display:flex;flex-direction:column;gap:4px}::ng-deep .process-link-properties-panel__title-container :last-child{color:var(--cds-text-helper);font-style:italic}::ng-deep .process-link-properties-panel .cds--tag{margin:0}::ng-deep .process-link-properties-panel .cds--btn{flex-shrink:1;width:100%;display:flex;align-items:center}\n/*!\n * Copyright 2015-2025 Ritense BV, the Netherlands.\n *\n * Licensed under EUPL, Version 1.2 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n"] }]
|
|
1589
1952
|
}], ctorParameters: () => [{ type: i1$1.BreadcrumbService }, { type: i2$2.IconService }, { type: i3.NGXLogger }, { type: i1$1.ModalService }, { type: i2$1.GlobalNotificationService }, { type: i1$1.PageHeaderService }, { type: i1$1.PageTitleService }, { type: i5.ProcessLinkService }, { type: i5.ProcessLinkStateService }, { type: ProcessManagementEditorService }, { type: ProcessManagementService }, { type: i7.ProcessService }, { type: i8.ActivatedRoute }, { type: i8.Router }, { type: i9.TranslateService }, { type: i10.PluginTranslationService }, { type: i2$1.EditPermissionsService }, { type: i5.ProcessLinkBuildingBlockApiService }], propDecorators: { modelerElementRef: [{
|
|
1590
1953
|
type: ViewChild,
|
|
1591
1954
|
args: ['modeler', { static: false }]
|
|
@@ -1635,7 +1998,19 @@ class ProcessManagementListComponent {
|
|
|
1635
1998
|
{ label: 'Delete', callback: this.onDeleteProcess.bind(this), type: 'danger' },
|
|
1636
1999
|
];
|
|
1637
2000
|
this.context$ = getContextObservable(this.route);
|
|
1638
|
-
this.processDefinitions$ =
|
|
2001
|
+
this.processDefinitions$ = combineLatest([
|
|
2002
|
+
this.processManagementStateService.reloadDefinitions$.pipe(tap(() => this.loading$.next(true)), switchMap(() => this.processManagementService.processes$), tap(() => this.loading$.next(false))),
|
|
2003
|
+
this.translateService.stream('key'),
|
|
2004
|
+
]).pipe(map$1(([definitions]) => definitions.map(def => {
|
|
2005
|
+
const tags = [];
|
|
2006
|
+
if (def.draft) {
|
|
2007
|
+
tags.push({ content: this.translateService.instant('processManagement.draft'), type: 'red' });
|
|
2008
|
+
}
|
|
2009
|
+
if (def.processDefinition?.readOnly) {
|
|
2010
|
+
tags.push({ content: this.translateService.instant('processManagement.readOnly'), type: 'gray' });
|
|
2011
|
+
}
|
|
2012
|
+
return { ...def, statusTags: tags };
|
|
2013
|
+
})));
|
|
1639
2014
|
this.hasEditPermissions$ = combineLatest([
|
|
1640
2015
|
getCaseManagementRouteParams(this.route),
|
|
1641
2016
|
this.context$,
|
|
@@ -1645,11 +2020,6 @@ class ProcessManagementListComponent {
|
|
|
1645
2020
|
this.FIELDS = [
|
|
1646
2021
|
{ key: 'processDefinition.name', label: 'processManagement.name' },
|
|
1647
2022
|
{ key: 'processDefinition.key', label: 'processManagement.key' },
|
|
1648
|
-
{
|
|
1649
|
-
key: 'processDefinition.readOnly',
|
|
1650
|
-
label: 'processManagement.readOnly',
|
|
1651
|
-
viewType: ViewType.BOOLEAN,
|
|
1652
|
-
},
|
|
1653
2023
|
...(this.processManagementService.$context() === 'case'
|
|
1654
2024
|
? [
|
|
1655
2025
|
{
|
|
@@ -1657,10 +2027,6 @@ class ProcessManagementListComponent {
|
|
|
1657
2027
|
label: 'processManagement.canInitializeDocument',
|
|
1658
2028
|
viewType: ViewType.BOOLEAN,
|
|
1659
2029
|
},
|
|
1660
|
-
]
|
|
1661
|
-
: []),
|
|
1662
|
-
...(this.processManagementService.$context() === 'case'
|
|
1663
|
-
? [
|
|
1664
2030
|
{
|
|
1665
2031
|
key: 'processCaseLink.startableByUser',
|
|
1666
2032
|
label: 'processManagement.startableByUser',
|
|
@@ -1668,6 +2034,12 @@ class ProcessManagementListComponent {
|
|
|
1668
2034
|
},
|
|
1669
2035
|
]
|
|
1670
2036
|
: []),
|
|
2037
|
+
{
|
|
2038
|
+
key: 'statusTags',
|
|
2039
|
+
label: 'processManagement.status',
|
|
2040
|
+
viewType: ViewType.TAGS,
|
|
2041
|
+
tagAmount: 2,
|
|
2042
|
+
},
|
|
1671
2043
|
];
|
|
1672
2044
|
this.iconService.registerAll([Upload16]);
|
|
1673
2045
|
}
|