@valtimo/decision 13.33.0 → 13.35.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-decision.mjs +644 -68
- package/fesm2022/valtimo-decision.mjs.map +1 -1
- package/lib/constants/decision.test-ids.d.ts +7 -0
- package/lib/constants/decision.test-ids.d.ts.map +1 -1
- package/lib/decision-form-modal/decision-form-modal.component.d.ts +38 -0
- package/lib/decision-form-modal/decision-form-modal.component.d.ts.map +1 -0
- package/lib/decision-list/decision-list.component.d.ts +25 -6
- package/lib/decision-list/decision-list.component.d.ts.map +1 -1
- package/lib/decision-modeler/decision-modeler.component.d.ts +21 -6
- package/lib/decision-modeler/decision-modeler.component.d.ts.map +1 -1
- package/lib/decision.module.d.ts +5 -4
- package/lib/decision.module.d.ts.map +1 -1
- package/lib/models/decision.model.d.ts +10 -0
- package/lib/models/decision.model.d.ts.map +1 -1
- package/lib/services/decision.service.d.ts +1 -0
- package/lib/services/decision.service.d.ts.map +1 -1
- package/lib/utils/dmn-template.d.ts +34 -0
- package/lib/utils/dmn-template.d.ts.map +1 -0
- package/package.json +1 -1
- package/public-api.d.ts +2 -0
- package/public-api.d.ts.map +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Injectable,
|
|
3
|
-
import { Subject, startWith, BehaviorSubject, map, combineLatest, switchMap, tap, filter, take, from, of, catchError } from 'rxjs';
|
|
2
|
+
import { Injectable, EventEmitter, signal, Output, Input, ChangeDetectionStrategy, Component, ViewChild, ViewEncapsulation, NgModule } from '@angular/core';
|
|
3
|
+
import { Subject, startWith, BehaviorSubject, map, combineLatest, switchMap, shareReplay, tap, filter, take, from, of, catchError } from 'rxjs';
|
|
4
4
|
import * as i1 from '@angular/common/http';
|
|
5
5
|
import { HttpHeaders } from '@angular/common/http';
|
|
6
6
|
import * as i6 from '@valtimo/shared';
|
|
@@ -11,17 +11,18 @@ import * as i7 from '@angular/common';
|
|
|
11
11
|
import { CommonModule } from '@angular/common';
|
|
12
12
|
import { AuthGuardService } from '@valtimo/security';
|
|
13
13
|
import DmnJS from 'dmn-js/dist/dmn-modeler.development.js';
|
|
14
|
-
import
|
|
15
|
-
import * as
|
|
16
|
-
import {
|
|
14
|
+
import DmnViewer from 'dmn-js/dist/dmn-viewer.development.js';
|
|
15
|
+
import * as i1$1 from '@angular/forms';
|
|
16
|
+
import { Validators, ReactiveFormsModule, FormsModule } from '@angular/forms';
|
|
17
17
|
import * as i3 from '@ngx-translate/core';
|
|
18
18
|
import { TranslateModule } from '@ngx-translate/core';
|
|
19
|
-
import * as
|
|
20
|
-
import {
|
|
21
|
-
import
|
|
22
|
-
import
|
|
23
|
-
import
|
|
24
|
-
import {
|
|
19
|
+
import * as i4$1 from '@valtimo/components';
|
|
20
|
+
import { runAfterCarbonModalClosed, ValtimoCdsModalDirective, CarbonMultiInputModule, PendingChangesComponent, WidgetModule, SelectModule as SelectModule$1, RenderInPageHeaderDirective, FitPageDirective, OverflowMenuComponent, OverflowMenuOptionComponent, OverflowMenuTriggerComponent, ConfirmationModalModule, CarbonListModule, ModalModule as ModalModule$1, SpinnerModule } from '@valtimo/components';
|
|
21
|
+
import * as i4 from 'carbon-components-angular';
|
|
22
|
+
import { ModalModule, ButtonModule, InputModule, LayerModule, SelectModule, IconModule, TagModule, FileUploaderModule } from 'carbon-components-angular';
|
|
23
|
+
import { migrateDiagram } from '@bpmn-io/dmn-migrate';
|
|
24
|
+
import { Deploy16, Download16, ArrowLeft16, Upload16, Add16 } from '@carbon/icons';
|
|
25
|
+
import DmnViewer$1 from 'dmn-js';
|
|
25
26
|
|
|
26
27
|
/*
|
|
27
28
|
* Copyright 2015-2025 Ritense BV, the Netherlands.
|
|
@@ -137,6 +138,10 @@ class DecisionService extends BaseApiService {
|
|
|
137
138
|
getDecisions() {
|
|
138
139
|
return this.httpClient.get(this.getApiUrl('/operaton-rest/engine/default/decision-definition'));
|
|
139
140
|
}
|
|
141
|
+
getUnlinkedDecisions() {
|
|
142
|
+
// Only the "global" decision tables: those not linked to a case or building block definition.
|
|
143
|
+
return this.httpClient.get(this.getApiUrl('/management/v1/decision-definition'));
|
|
144
|
+
}
|
|
140
145
|
getDecisionById(decisionId) {
|
|
141
146
|
return this.httpClient.get(this.getApiUrl(`/operaton-rest/engine/default/decision-definition/${decisionId}`));
|
|
142
147
|
}
|
|
@@ -215,13 +220,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImpo
|
|
|
215
220
|
*/
|
|
216
221
|
const DECISION_LIST_TEST_IDS = {
|
|
217
222
|
uploadButton: 'decisionListUploadButton',
|
|
223
|
+
createButton: 'decisionListCreateButton',
|
|
218
224
|
};
|
|
219
225
|
const DECISION_UPLOAD_TEST_IDS = {
|
|
220
226
|
submitButton: 'decisionUploadModalSubmitButton',
|
|
221
227
|
};
|
|
228
|
+
const DECISION_FORM_TEST_IDS = {
|
|
229
|
+
nameInput: 'decisionFormModalNameInput',
|
|
230
|
+
inputVariables: 'decisionFormModalInputVariables',
|
|
231
|
+
submitButton: 'decisionFormModalSubmitButton',
|
|
232
|
+
};
|
|
222
233
|
const DECISION_MODELER_TEST_IDS = {
|
|
223
234
|
deployButton: 'decisionModelerDeployButton',
|
|
224
235
|
backButton: 'decisionModelerBackButton',
|
|
236
|
+
readOnlyTag: 'decisionModelerReadOnlyTag',
|
|
225
237
|
};
|
|
226
238
|
|
|
227
239
|
/*
|
|
@@ -240,6 +252,348 @@ const DECISION_MODELER_TEST_IDS = {
|
|
|
240
252
|
* limitations under the License.
|
|
241
253
|
*/
|
|
242
254
|
|
|
255
|
+
/*
|
|
256
|
+
* Copyright 2015-2026 Ritense BV, the Netherlands.
|
|
257
|
+
*
|
|
258
|
+
* Licensed under EUPL, Version 1.2 (the "License");
|
|
259
|
+
* you may not use this file except in compliance with the License.
|
|
260
|
+
* You may obtain a copy of the License at
|
|
261
|
+
*
|
|
262
|
+
* https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
|
|
263
|
+
*
|
|
264
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
265
|
+
* distributed under the License is distributed on an "AS IS" basis,
|
|
266
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
267
|
+
* See the License for the specific language governing permissions and
|
|
268
|
+
* limitations under the License.
|
|
269
|
+
*/
|
|
270
|
+
const DEFAULT_DECISION_KEY = 'decision';
|
|
271
|
+
function escapeXmlAttribute(value) {
|
|
272
|
+
return value
|
|
273
|
+
.replace(/&/g, '&')
|
|
274
|
+
.replace(/</g, '<')
|
|
275
|
+
.replace(/>/g, '>')
|
|
276
|
+
.replace(/"/g, '"')
|
|
277
|
+
.replace(/'/g, ''');
|
|
278
|
+
}
|
|
279
|
+
function escapeXmlText(value) {
|
|
280
|
+
return value.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Derives a valid DMN decision key (an XML NCName) from a human-readable name.
|
|
284
|
+
* The decision key doubles as the identifier referenced from a process'
|
|
285
|
+
* business rule task, so it must be a stable, valid identifier.
|
|
286
|
+
*/
|
|
287
|
+
function toDecisionKey(name) {
|
|
288
|
+
const cleaned = (name ?? '')
|
|
289
|
+
.trim()
|
|
290
|
+
.replace(/[^A-Za-z0-9_-]+/g, '_')
|
|
291
|
+
.replace(/^[_-]+|[_-]+$/g, '');
|
|
292
|
+
if (!cleaned)
|
|
293
|
+
return DEFAULT_DECISION_KEY;
|
|
294
|
+
return /^[A-Za-z_]/.test(cleaned) ? cleaned : `${DEFAULT_DECISION_KEY}_${cleaned}`;
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Derives the name of the `.dmn` file that is deployed for a created decision.
|
|
298
|
+
*/
|
|
299
|
+
function toDecisionFileName(name) {
|
|
300
|
+
return `${toDecisionKey(name)}.dmn`;
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Normalizes input columns: trims label/expression, drops rows without a process
|
|
304
|
+
* variable (the expression is required), defaults the label to the process
|
|
305
|
+
* variable name when it is left blank, and guarantees at least one (empty) input
|
|
306
|
+
* column so the decision table always has an input to work with.
|
|
307
|
+
*/
|
|
308
|
+
function normalizeInputVariables(inputVariables) {
|
|
309
|
+
const cleaned = (inputVariables ?? [])
|
|
310
|
+
.map(({ label, expression }) => ({
|
|
311
|
+
label: (label ?? '').trim(),
|
|
312
|
+
expression: (expression ?? '').trim(),
|
|
313
|
+
}))
|
|
314
|
+
.filter(({ expression }) => expression.length > 0)
|
|
315
|
+
.map(({ label, expression }) => ({ label: label || expression, expression }));
|
|
316
|
+
return cleaned.length ? cleaned : [{ label: '', expression: '' }];
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Builds a deployable DMN 1.3 decision table seeded with one input column per
|
|
320
|
+
* provided input variable and a single output. Each input column gets its
|
|
321
|
+
* process variable as the input expression and, optionally, a human-readable
|
|
322
|
+
* label as the column header. Seeding this up front means the created table is
|
|
323
|
+
* functional immediately - the user only has to add rules before deploying.
|
|
324
|
+
*/
|
|
325
|
+
function createDmnXml({ name, inputVariables }) {
|
|
326
|
+
const key = toDecisionKey(name);
|
|
327
|
+
const safeName = escapeXmlAttribute((name ?? '').trim() || key);
|
|
328
|
+
const inputs = normalizeInputVariables(inputVariables);
|
|
329
|
+
const inputsXml = inputs
|
|
330
|
+
.map(({ label, expression }, index) => {
|
|
331
|
+
const labelAttr = label ? ` label="${escapeXmlAttribute(label)}"` : '';
|
|
332
|
+
return ` <input id="Input_${index + 1}"${labelAttr}>
|
|
333
|
+
<inputExpression id="InputExpression_${index + 1}" typeRef="string">
|
|
334
|
+
<text>${escapeXmlText(expression)}</text>
|
|
335
|
+
</inputExpression>
|
|
336
|
+
</input>`;
|
|
337
|
+
})
|
|
338
|
+
.join('\n');
|
|
339
|
+
const inputEntriesXml = inputs
|
|
340
|
+
.map((_, index) => ` <inputEntry id="UnaryTests_${index + 1}">
|
|
341
|
+
<text></text>
|
|
342
|
+
</inputEntry>`)
|
|
343
|
+
.join('\n');
|
|
344
|
+
const dmnXml = `<?xml version="1.0" encoding="UTF-8"?>
|
|
345
|
+
<definitions xmlns="https://www.omg.org/spec/DMN/20191111/MODEL/" xmlns:dmndi="https://www.omg.org/spec/DMN/20191111/DMNDI/" xmlns:dc="http://www.omg.org/spec/DMN/20180521/DC/" id="Definitions_${key}" name="${safeName}" namespace="http://camunda.org/schema/1.0/dmn">
|
|
346
|
+
<decision id="${key}" name="${safeName}">
|
|
347
|
+
<decisionTable id="DecisionTable_${key}">
|
|
348
|
+
${inputsXml}
|
|
349
|
+
<output id="Output_1" label="Output" name="result" typeRef="string" />
|
|
350
|
+
<rule id="DecisionRule_1">
|
|
351
|
+
${inputEntriesXml}
|
|
352
|
+
<outputEntry id="LiteralExpression_1">
|
|
353
|
+
<text></text>
|
|
354
|
+
</outputEntry>
|
|
355
|
+
</rule>
|
|
356
|
+
</decisionTable>
|
|
357
|
+
</decision>
|
|
358
|
+
<dmndi:DMNDI>
|
|
359
|
+
<dmndi:DMNDiagram>
|
|
360
|
+
<dmndi:DMNShape dmnElementRef="${key}">
|
|
361
|
+
<dc:Bounds height="80" width="180" x="160" y="100" />
|
|
362
|
+
</dmndi:DMNShape>
|
|
363
|
+
</dmndi:DMNDiagram>
|
|
364
|
+
</dmndi:DMNDI>
|
|
365
|
+
</definitions>
|
|
366
|
+
`;
|
|
367
|
+
return { id: '', dmnXml };
|
|
368
|
+
}
|
|
369
|
+
function childrenByLocalName(parent, localName) {
|
|
370
|
+
return Array.from(parent.children).filter(child => child.localName === localName);
|
|
371
|
+
}
|
|
372
|
+
function firstChildByLocalName(parent, localName) {
|
|
373
|
+
return childrenByLocalName(parent, localName)[0] ?? null;
|
|
374
|
+
}
|
|
375
|
+
function uniqueId(doc, prefix) {
|
|
376
|
+
let id;
|
|
377
|
+
do {
|
|
378
|
+
id = `${prefix}_${Math.random().toString(36).slice(2, 10)}`;
|
|
379
|
+
} while (doc.querySelector(`[id="${id}"]`));
|
|
380
|
+
return id;
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Reads the editable form values (decision name and input columns) from an
|
|
384
|
+
* existing DMN XML document.
|
|
385
|
+
*/
|
|
386
|
+
function parseDecisionForm(xml) {
|
|
387
|
+
const doc = new DOMParser().parseFromString(xml, 'application/xml');
|
|
388
|
+
const decision = doc.getElementsByTagNameNS('*', 'decision')[0];
|
|
389
|
+
const name = decision?.getAttribute('name') || decision?.getAttribute('id') || '';
|
|
390
|
+
const inputVariables = Array.from(doc.getElementsByTagNameNS('*', 'input')).map(input => {
|
|
391
|
+
const inputExpression = input.getElementsByTagNameNS('*', 'inputExpression')[0];
|
|
392
|
+
const text = inputExpression?.getElementsByTagNameNS('*', 'text')[0];
|
|
393
|
+
const expression = (text?.textContent ?? '').trim();
|
|
394
|
+
const label = (input.getAttribute('label') ?? '').trim();
|
|
395
|
+
// A label equal to the expression means it was defaulted, so present it as blank.
|
|
396
|
+
return { label: label === expression ? '' : label, expression };
|
|
397
|
+
});
|
|
398
|
+
return { name, inputVariables };
|
|
399
|
+
}
|
|
400
|
+
function setInputColumn(input, { label, expression }, doc, ns) {
|
|
401
|
+
if (label) {
|
|
402
|
+
input.setAttribute('label', label);
|
|
403
|
+
}
|
|
404
|
+
else {
|
|
405
|
+
input.removeAttribute('label');
|
|
406
|
+
}
|
|
407
|
+
let inputExpression = firstChildByLocalName(input, 'inputExpression');
|
|
408
|
+
if (!inputExpression) {
|
|
409
|
+
inputExpression = doc.createElementNS(ns, 'inputExpression');
|
|
410
|
+
inputExpression.setAttribute('id', uniqueId(doc, 'InputExpression'));
|
|
411
|
+
inputExpression.setAttribute('typeRef', 'string');
|
|
412
|
+
input.appendChild(inputExpression);
|
|
413
|
+
}
|
|
414
|
+
let text = firstChildByLocalName(inputExpression, 'text');
|
|
415
|
+
if (!text) {
|
|
416
|
+
text = doc.createElementNS(ns, 'text');
|
|
417
|
+
inputExpression.appendChild(text);
|
|
418
|
+
}
|
|
419
|
+
text.textContent = expression;
|
|
420
|
+
}
|
|
421
|
+
function createInputElement(inputVariable, doc, ns) {
|
|
422
|
+
const input = doc.createElementNS(ns, 'input');
|
|
423
|
+
input.setAttribute('id', uniqueId(doc, 'Input'));
|
|
424
|
+
setInputColumn(input, inputVariable, doc, ns);
|
|
425
|
+
return input;
|
|
426
|
+
}
|
|
427
|
+
function createEmptyInputEntry(doc, ns) {
|
|
428
|
+
const entry = doc.createElementNS(ns, 'inputEntry');
|
|
429
|
+
entry.setAttribute('id', uniqueId(doc, 'UnaryTests'));
|
|
430
|
+
const text = doc.createElementNS(ns, 'text');
|
|
431
|
+
text.textContent = '';
|
|
432
|
+
entry.appendChild(text);
|
|
433
|
+
return entry;
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* Patches an existing DMN XML document with a new decision name and set of input
|
|
437
|
+
* columns, while preserving the decision key, outputs, rules and diagram. Input
|
|
438
|
+
* columns are reconciled positionally: existing columns are updated (label +
|
|
439
|
+
* expression), extra columns add an input (and a blank entry to every rule), and
|
|
440
|
+
* removed columns drop the input (and their rule entries).
|
|
441
|
+
*/
|
|
442
|
+
function updateDmnXml(xml, { name, inputVariables }) {
|
|
443
|
+
const doc = new DOMParser().parseFromString(xml, 'application/xml');
|
|
444
|
+
if (doc.getElementsByTagName('parsererror').length > 0) {
|
|
445
|
+
return xml;
|
|
446
|
+
}
|
|
447
|
+
const trimmedName = (name ?? '').trim();
|
|
448
|
+
const decision = doc.getElementsByTagNameNS('*', 'decision')[0];
|
|
449
|
+
if (decision && trimmedName) {
|
|
450
|
+
decision.setAttribute('name', trimmedName);
|
|
451
|
+
}
|
|
452
|
+
const decisionTable = doc.getElementsByTagNameNS('*', 'decisionTable')[0];
|
|
453
|
+
if (!decisionTable) {
|
|
454
|
+
return new XMLSerializer().serializeToString(doc);
|
|
455
|
+
}
|
|
456
|
+
const ns = decisionTable.namespaceURI;
|
|
457
|
+
const targets = normalizeInputVariables(inputVariables);
|
|
458
|
+
const existingInputs = childrenByLocalName(decisionTable, 'input');
|
|
459
|
+
const rules = childrenByLocalName(decisionTable, 'rule');
|
|
460
|
+
// Build the final ordered list of input columns, reusing existing nodes where possible.
|
|
461
|
+
const finalInputs = targets.map((inputVariable, index) => {
|
|
462
|
+
const existing = existingInputs[index];
|
|
463
|
+
if (existing) {
|
|
464
|
+
setInputColumn(existing, inputVariable, doc, ns);
|
|
465
|
+
return existing;
|
|
466
|
+
}
|
|
467
|
+
return createInputElement(inputVariable, doc, ns);
|
|
468
|
+
});
|
|
469
|
+
// Remove all existing inputs, then re-insert the final ones in order before the outputs/rules.
|
|
470
|
+
existingInputs.forEach(input => input.remove());
|
|
471
|
+
const anchor = firstChildByLocalName(decisionTable, 'output') ??
|
|
472
|
+
firstChildByLocalName(decisionTable, 'rule') ??
|
|
473
|
+
null;
|
|
474
|
+
finalInputs.forEach(input => decisionTable.insertBefore(input, anchor));
|
|
475
|
+
// Reconcile each rule's input entries to match the number of input columns.
|
|
476
|
+
rules.forEach(rule => {
|
|
477
|
+
const entries = childrenByLocalName(rule, 'inputEntry');
|
|
478
|
+
for (let index = entries.length; index < finalInputs.length; index++) {
|
|
479
|
+
const firstOutputEntry = firstChildByLocalName(rule, 'outputEntry');
|
|
480
|
+
rule.insertBefore(createEmptyInputEntry(doc, ns), firstOutputEntry);
|
|
481
|
+
}
|
|
482
|
+
for (let index = entries.length - 1; index >= finalInputs.length; index--) {
|
|
483
|
+
entries[index].remove();
|
|
484
|
+
}
|
|
485
|
+
});
|
|
486
|
+
return new XMLSerializer().serializeToString(doc);
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
/*
|
|
490
|
+
* Copyright 2015-2026 Ritense BV, the Netherlands.
|
|
491
|
+
*
|
|
492
|
+
* Licensed under EUPL, Version 1.2 (the "License");
|
|
493
|
+
* you may not use this file except in compliance with the License.
|
|
494
|
+
* You may obtain a copy of the License at
|
|
495
|
+
*
|
|
496
|
+
* https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
|
|
497
|
+
*
|
|
498
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
499
|
+
* distributed under the License is distributed on an "AS IS" basis,
|
|
500
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
501
|
+
* See the License for the specific language governing permissions and
|
|
502
|
+
* limitations under the License.
|
|
503
|
+
*/
|
|
504
|
+
class DecisionFormModalComponent {
|
|
505
|
+
get name() {
|
|
506
|
+
return this.form.get('name');
|
|
507
|
+
}
|
|
508
|
+
constructor(formBuilder) {
|
|
509
|
+
this.formBuilder = formBuilder;
|
|
510
|
+
this.titleKey = 'decisions.createModal.title';
|
|
511
|
+
this.submitKey = 'interface.create';
|
|
512
|
+
this.submitEvent = new EventEmitter();
|
|
513
|
+
this.MAX_INPUT_VARIABLES = 100;
|
|
514
|
+
this.modalOpen$ = new BehaviorSubject(false);
|
|
515
|
+
this.defaultInputVariables$ = new BehaviorSubject([
|
|
516
|
+
{ key: '', value: '' },
|
|
517
|
+
]);
|
|
518
|
+
/** True when a row has a label but no process variable (the process variable is required). */
|
|
519
|
+
this.$inputVariablesInvalid = signal(false);
|
|
520
|
+
this.testIds = DECISION_FORM_TEST_IDS;
|
|
521
|
+
this.form = this.formBuilder.group({
|
|
522
|
+
name: this.formBuilder.control('', [Validators.required]),
|
|
523
|
+
});
|
|
524
|
+
this._inputVariables = [];
|
|
525
|
+
}
|
|
526
|
+
open(initial) {
|
|
527
|
+
const inputVariables = initial?.inputVariables ?? [];
|
|
528
|
+
this._inputVariables = inputVariables.map(({ label, expression }) => ({ label, expression }));
|
|
529
|
+
// The multi-input renders key (left) then value (right); the process variable is
|
|
530
|
+
// the first column, so it maps to key and the label maps to value.
|
|
531
|
+
this.defaultInputVariables$.next(inputVariables.length
|
|
532
|
+
? inputVariables.map(({ label, expression }) => ({ key: expression, value: label }))
|
|
533
|
+
: [{ key: '', value: '' }]);
|
|
534
|
+
this.updateInputVariablesValidity();
|
|
535
|
+
this.form.reset({ name: initial?.name ?? '' });
|
|
536
|
+
this.modalOpen$.next(true);
|
|
537
|
+
}
|
|
538
|
+
/** Convenience used by the "create" trigger, which opens an empty form. */
|
|
539
|
+
openModal() {
|
|
540
|
+
this.open();
|
|
541
|
+
}
|
|
542
|
+
closeModal() {
|
|
543
|
+
this.modalOpen$.next(false);
|
|
544
|
+
runAfterCarbonModalClosed(() => {
|
|
545
|
+
this.form.reset({ name: '' });
|
|
546
|
+
this._inputVariables = [];
|
|
547
|
+
this.$inputVariablesInvalid.set(false);
|
|
548
|
+
this.defaultInputVariables$.next([{ key: '', value: '' }]);
|
|
549
|
+
});
|
|
550
|
+
}
|
|
551
|
+
onInputVariablesChange(values) {
|
|
552
|
+
this._inputVariables = (values ?? []).map(row => ({
|
|
553
|
+
label: row.value ?? '',
|
|
554
|
+
expression: row.key ?? '',
|
|
555
|
+
}));
|
|
556
|
+
this.updateInputVariablesValidity();
|
|
557
|
+
}
|
|
558
|
+
submit() {
|
|
559
|
+
if (this.form.invalid || this.$inputVariablesInvalid()) {
|
|
560
|
+
this.form.markAllAsTouched();
|
|
561
|
+
return;
|
|
562
|
+
}
|
|
563
|
+
const name = (this.form.getRawValue().name ?? '').trim();
|
|
564
|
+
const inputVariables = this._inputVariables
|
|
565
|
+
.map(({ label, expression }) => ({ label: label.trim(), expression: expression.trim() }))
|
|
566
|
+
.filter(({ expression }) => expression.length > 0);
|
|
567
|
+
this.submitEvent.emit({ name, inputVariables });
|
|
568
|
+
this.closeModal();
|
|
569
|
+
}
|
|
570
|
+
updateInputVariablesValidity() {
|
|
571
|
+
this.$inputVariablesInvalid.set(this._inputVariables.some(({ label, expression }) => label.trim().length > 0 && expression.trim().length === 0));
|
|
572
|
+
}
|
|
573
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: DecisionFormModalComponent, deps: [{ token: i1$1.FormBuilder }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
574
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.20", type: DecisionFormModalComponent, isStandalone: true, selector: "valtimo-decision-form-modal", inputs: { titleKey: "titleKey", submitKey: "submitKey" }, outputs: { submitEvent: "submitEvent" }, 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<cds-modal showFooter=\"true\" valtimoCdsModal [open]=\"modalOpen$ | async\" (close)=\"closeModal()\">\n <cds-modal-header showCloseButton=\"true\" (closeSelect)=\"closeModal()\">\n <h3 cdsModalHeaderHeading>{{ titleKey | translate }}</h3>\n </cds-modal-header>\n\n <form cdsModalContent [cdsLayer]=\"1\" [formGroup]=\"form\">\n <div class=\"cds--text-input__field-wrapper\">\n <cds-label [invalid]=\"name.touched && name.invalid\">\n <span>{{ 'decisions.createModal.name' | translate }}</span>\n\n <input\n cdsText\n formControlName=\"name\"\n [attr.data-test-id]=\"testIds.nameInput\"\n [invalid]=\"name.touched && name.invalid\"\n placeholder=\"{{ 'decisions.createModal.namePlaceholder' | translate }}\"\n />\n </cds-label>\n\n <div *ngIf=\"name.touched && name.invalid\" class=\"cds--form-requirement\">\n {{ 'decisions.createModal.nameRequired' | translate }}\n </div>\n </div>\n\n <valtimo-carbon-multi-input\n *ngIf=\"modalOpen$ | async\"\n type=\"keyValue\"\n [attr.data-test-id]=\"testIds.inputVariables\"\n [titleTranslationKey]=\"'decisions.createModal.inputVariables'\"\n [tooltip]=\"'decisions.createModal.inputVariablesHelper' | translate\"\n [keyColumnTitle]=\"'decisions.createModal.inputExpression' | translate\"\n [valueColumnTitle]=\"'decisions.createModal.inputLabel' | translate\"\n [addRowTranslationKey]=\"'decisions.createModal.addInputVariable'\"\n [defaultValues]=\"defaultInputVariables$ | async\"\n [initialAmountOfRows]=\"1\"\n [minimumAmountOfRows]=\"1\"\n [maxRows]=\"MAX_INPUT_VARIABLES\"\n [margin]=\"true\"\n [fullWidth]=\"true\"\n (valueChange)=\"onInputVariablesChange($event)\"\n ></valtimo-carbon-multi-input>\n\n <div *ngIf=\"$inputVariablesInvalid()\" class=\"cds--form-requirement\">\n {{ 'decisions.createModal.inputExpressionRequired' | translate }}\n </div>\n </form>\n\n <cds-modal-footer>\n <button cdsButton=\"secondary\" (click)=\"closeModal()\">\n {{ 'interface.cancel' | translate }}\n </button>\n\n <button\n cdsButton=\"primary\"\n [disabled]=\"form.invalid || $inputVariablesInvalid()\"\n (click)=\"submit()\"\n [attr.data-test-id]=\"testIds.submitButton\"\n >\n {{ submitKey | translate }}\n </button>\n </cds-modal-footer>\n</cds-modal>\n", styles: [":host ::ng-deep cds-label{width:100%}.cds--modal-content{display:flex;flex-direction:column;gap:16px}\n/*!\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"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i7.AsyncPipe, name: "async" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: ModalModule }, { kind: "component", type: i4.Modal, selector: "cds-modal, ibm-modal", inputs: ["size", "theme", "ariaLabel", "open", "trigger", "hasScrollingContent"], outputs: ["overlaySelected", "close"] }, { kind: "component", type: i4.ModalHeader, selector: "cds-modal-header, ibm-modal-header", inputs: ["theme", "closeLabel", "showCloseButton"], outputs: ["closeSelect"] }, { kind: "component", type: i4.ModalFooter, selector: "cds-modal-footer, ibm-modal-footer" }, { kind: "directive", type: i4.ModalContent, selector: "[cdsModalContent], [ibmModalContent]", inputs: ["hasForm"] }, { kind: "directive", type: i4.ModalHeaderHeading, selector: "[cdsModalHeaderHeading], [ibmModalHeaderHeading]" }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i4.Button, selector: "[cdsButton], [ibmButton]", inputs: ["ibmButton", "cdsButton", "size", "skeleton", "iconOnly", "isExpressive"] }, { kind: "ngmodule", type: InputModule }, { kind: "component", type: i4.Label, selector: "cds-label, ibm-label", inputs: ["labelInputID", "disabled", "skeleton", "helperText", "invalidText", "invalid", "warn", "warnText", "ariaLabel"] }, { kind: "directive", type: i4.TextInput, selector: "[cdsText], [ibmText]", inputs: ["theme", "size", "invalid", "warn", "skeleton"] }, { kind: "ngmodule", type: LayerModule }, { kind: "directive", type: i4.LayerDirective, selector: "[cdsLayer], [ibmLayer]", inputs: ["ibmLayer", "cdsLayer"], exportAs: ["layer"] }, { kind: "directive", type: ValtimoCdsModalDirective, selector: "[valtimoCdsModal]", inputs: ["minContentHeight"] }, { kind: "ngmodule", type: CarbonMultiInputModule }, { kind: "component", type: i4$1.CarbonMultiInputComponent, selector: "valtimo-carbon-multi-input", inputs: ["addRowText", "addButtonType", "addRowTranslationKey", "arbitraryAmountTitles", "arbitraryValueAmount", "defaultValues", "deleteRowText", "deleteRowTranslationKey", "disabled", "dropdownColumnTitle", "dropdownItems", "dropdownWidth", "fullWidth", "hideAddButton", "hideDeleteButton", "initialAmountOfRows", "keyColumnTitle", "margin", "maxRows", "minimumAmountOfRows", "name", "required", "title", "titleTranslationKey", "tooltip", "type", "valueColumnTitle", "valuePathSelectorCaseDefinitionKey", "valuePathSelectorPrefixes", "valuePathSelectorShowCaseDefinitionSelector", "valuePathSelectorNotation", "keyColumnFlex", "dropdownColumnFlex", "valueColumnFlex"], outputs: ["valueChange", "allValuesValidEvent"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
575
|
+
}
|
|
576
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: DecisionFormModalComponent, decorators: [{
|
|
577
|
+
type: Component,
|
|
578
|
+
args: [{ selector: 'valtimo-decision-form-modal', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
579
|
+
CommonModule,
|
|
580
|
+
ReactiveFormsModule,
|
|
581
|
+
TranslateModule,
|
|
582
|
+
ModalModule,
|
|
583
|
+
ButtonModule,
|
|
584
|
+
InputModule,
|
|
585
|
+
LayerModule,
|
|
586
|
+
ValtimoCdsModalDirective,
|
|
587
|
+
CarbonMultiInputModule,
|
|
588
|
+
], 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<cds-modal showFooter=\"true\" valtimoCdsModal [open]=\"modalOpen$ | async\" (close)=\"closeModal()\">\n <cds-modal-header showCloseButton=\"true\" (closeSelect)=\"closeModal()\">\n <h3 cdsModalHeaderHeading>{{ titleKey | translate }}</h3>\n </cds-modal-header>\n\n <form cdsModalContent [cdsLayer]=\"1\" [formGroup]=\"form\">\n <div class=\"cds--text-input__field-wrapper\">\n <cds-label [invalid]=\"name.touched && name.invalid\">\n <span>{{ 'decisions.createModal.name' | translate }}</span>\n\n <input\n cdsText\n formControlName=\"name\"\n [attr.data-test-id]=\"testIds.nameInput\"\n [invalid]=\"name.touched && name.invalid\"\n placeholder=\"{{ 'decisions.createModal.namePlaceholder' | translate }}\"\n />\n </cds-label>\n\n <div *ngIf=\"name.touched && name.invalid\" class=\"cds--form-requirement\">\n {{ 'decisions.createModal.nameRequired' | translate }}\n </div>\n </div>\n\n <valtimo-carbon-multi-input\n *ngIf=\"modalOpen$ | async\"\n type=\"keyValue\"\n [attr.data-test-id]=\"testIds.inputVariables\"\n [titleTranslationKey]=\"'decisions.createModal.inputVariables'\"\n [tooltip]=\"'decisions.createModal.inputVariablesHelper' | translate\"\n [keyColumnTitle]=\"'decisions.createModal.inputExpression' | translate\"\n [valueColumnTitle]=\"'decisions.createModal.inputLabel' | translate\"\n [addRowTranslationKey]=\"'decisions.createModal.addInputVariable'\"\n [defaultValues]=\"defaultInputVariables$ | async\"\n [initialAmountOfRows]=\"1\"\n [minimumAmountOfRows]=\"1\"\n [maxRows]=\"MAX_INPUT_VARIABLES\"\n [margin]=\"true\"\n [fullWidth]=\"true\"\n (valueChange)=\"onInputVariablesChange($event)\"\n ></valtimo-carbon-multi-input>\n\n <div *ngIf=\"$inputVariablesInvalid()\" class=\"cds--form-requirement\">\n {{ 'decisions.createModal.inputExpressionRequired' | translate }}\n </div>\n </form>\n\n <cds-modal-footer>\n <button cdsButton=\"secondary\" (click)=\"closeModal()\">\n {{ 'interface.cancel' | translate }}\n </button>\n\n <button\n cdsButton=\"primary\"\n [disabled]=\"form.invalid || $inputVariablesInvalid()\"\n (click)=\"submit()\"\n [attr.data-test-id]=\"testIds.submitButton\"\n >\n {{ submitKey | translate }}\n </button>\n </cds-modal-footer>\n</cds-modal>\n", styles: [":host ::ng-deep cds-label{width:100%}.cds--modal-content{display:flex;flex-direction:column;gap:16px}\n/*!\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"] }]
|
|
589
|
+
}], ctorParameters: () => [{ type: i1$1.FormBuilder }], propDecorators: { titleKey: [{
|
|
590
|
+
type: Input
|
|
591
|
+
}], submitKey: [{
|
|
592
|
+
type: Input
|
|
593
|
+
}], submitEvent: [{
|
|
594
|
+
type: Output
|
|
595
|
+
}] } });
|
|
596
|
+
|
|
243
597
|
/*
|
|
244
598
|
* Copyright 2015-2025 Ritense BV, the Netherlands.
|
|
245
599
|
*
|
|
@@ -296,7 +650,7 @@ const EMPTY_DECISION = {
|
|
|
296
650
|
* limitations under the License.
|
|
297
651
|
*/
|
|
298
652
|
class DecisionModelerComponent extends PendingChangesComponent {
|
|
299
|
-
constructor(decisionService, route, router, translateService, pageTitleService, breadcrumbService, iconService, pageHeaderService, notificationService, editPermissionsService) {
|
|
653
|
+
constructor(decisionService, route, router, translateService, pageTitleService, breadcrumbService, iconService, pageHeaderService, notificationService, editPermissionsService, draftVersionService) {
|
|
300
654
|
super();
|
|
301
655
|
this.decisionService = decisionService;
|
|
302
656
|
this.route = route;
|
|
@@ -308,6 +662,7 @@ class DecisionModelerComponent extends PendingChangesComponent {
|
|
|
308
662
|
this.pageHeaderService = pageHeaderService;
|
|
309
663
|
this.notificationService = notificationService;
|
|
310
664
|
this.editPermissionsService = editPermissionsService;
|
|
665
|
+
this.draftVersionService = draftVersionService;
|
|
311
666
|
this.CLASS_NAMES = {
|
|
312
667
|
drd: 'dmn-icon-lasso-tool',
|
|
313
668
|
decisionTable: 'dmn-icon-decision-table',
|
|
@@ -317,6 +672,11 @@ class DecisionModelerComponent extends PendingChangesComponent {
|
|
|
317
672
|
this.versionSelectionDisabled$ = new BehaviorSubject(true);
|
|
318
673
|
this.isCreating$ = new BehaviorSubject(false);
|
|
319
674
|
this.selectionId$ = new BehaviorSubject('');
|
|
675
|
+
this.showDeleteModal$ = new BehaviorSubject(false);
|
|
676
|
+
// Emits once the dmn-js editor instance has been created, so XML import can wait for it.
|
|
677
|
+
this._editorReady$ = new BehaviorSubject(false);
|
|
678
|
+
this._createSeed = null;
|
|
679
|
+
this._decisionKey = null;
|
|
320
680
|
this.caseManagementRouteParams$ = getCaseManagementRouteParams(this.route);
|
|
321
681
|
this.buildingBlockManagementRouteParams$ = getBuildingBlockManagementRouteParams(this.route);
|
|
322
682
|
this.context$ = getContextObservable(this.route);
|
|
@@ -324,38 +684,74 @@ class DecisionModelerComponent extends PendingChangesComponent {
|
|
|
324
684
|
this.compactMode$ = this.pageHeaderService.compactMode$;
|
|
325
685
|
this.hasEditPermissions$ = combineLatest([
|
|
326
686
|
this.caseManagementRouteParams$,
|
|
687
|
+
this.buildingBlockManagementRouteParams$,
|
|
327
688
|
this.context$,
|
|
328
|
-
]).pipe(switchMap(([
|
|
689
|
+
]).pipe(switchMap(([caseParams, buildingBlockParams, context]) => {
|
|
690
|
+
// Building block decision tables can only be edited on a draft (non-final) version.
|
|
691
|
+
if (context === 'buildingBlock') {
|
|
692
|
+
return this.draftVersionService.isDraftVersionBuildingBlock(buildingBlockParams?.buildingBlockDefinitionKey ?? '', buildingBlockParams?.buildingBlockDefinitionVersionTag ?? '');
|
|
693
|
+
}
|
|
694
|
+
return this.editPermissionsService.hasPermissionsToEditBasedOnContext(caseParams, context ?? '');
|
|
695
|
+
}), shareReplay({ bufferSize: 1, refCount: false }));
|
|
696
|
+
// The editor is shown as a read-only viewer when the user cannot edit (e.g. a final case or
|
|
697
|
+
// building block definition) and is not creating a new decision table.
|
|
698
|
+
this.readOnly$ = combineLatest([
|
|
699
|
+
this.isCreating$,
|
|
700
|
+
this.hasEditPermissions$,
|
|
701
|
+
]).pipe(map(([isCreating, hasEditPermissions]) => !isCreating && !hasEditPermissions));
|
|
329
702
|
this.decisionId$ = this.route.params.pipe(map(params => params?.id), tap(id => {
|
|
330
703
|
this.isCreating$.next(id === 'create');
|
|
331
704
|
this.versionSelectionDisabled$.next(true);
|
|
332
705
|
}), filter(id => !!id && id !== 'create'));
|
|
333
706
|
this.decision$ = this.decisionId$.pipe(switchMap(id => this.decisionService.getDecisionById(id)), tap(decision => {
|
|
334
707
|
this._fileName = decision.resource;
|
|
708
|
+
this._decisionKey = decision?.key ?? null;
|
|
335
709
|
if (decision)
|
|
336
710
|
this.selectionId$.next(decision.id);
|
|
337
711
|
}));
|
|
338
712
|
this.decisionTitle$ = this.decision$.pipe(map(d => d?.name || d?.key || '-'), tap(title => this.pageTitleService.setCustomPageTitle(title)));
|
|
339
713
|
this._refreshDecisionSelectItems$ = new BehaviorSubject(null);
|
|
340
|
-
this.decisionVersionSelectItems$ = this._refreshDecisionSelectItems$.pipe(switchMap(() => combineLatest([this.decision$, this.decisionService.
|
|
714
|
+
this.decisionVersionSelectItems$ = this._refreshDecisionSelectItems$.pipe(switchMap(() => combineLatest([this.decision$, this.decisionService.getUnlinkedDecisions()])), map(([current, list]) => {
|
|
341
715
|
const filtered = list.filter(d => d.key === current.key);
|
|
342
716
|
return [...filtered.map(d => ({ id: d.id, text: d.version.toString() }))].sort((a, b) => +(b.text ?? '') - +(a.text ?? ''));
|
|
343
717
|
}), tap(() => this.versionSelectionDisabled$.next(false)));
|
|
344
|
-
this.decisionXml$ = this.decisionId$.pipe(switchMap(id => this.decisionService.getDecisionXml(id)),
|
|
718
|
+
this.decisionXml$ = this.decisionId$.pipe(switchMap(id => this.decisionService.getDecisionXml(id)),
|
|
719
|
+
// Wait until the editor (modeler or read-only viewer) has been created before importing.
|
|
720
|
+
switchMap(xml => this._editorReady$.pipe(filter(Boolean), take(1), map(() => xml))), tap(xml => xml && this.loadDecisionXml(xml)));
|
|
345
721
|
this.iconService.registerAll([Deploy16, Download16, ArrowLeft16]);
|
|
722
|
+
this._createSeed = this.extractCreateSeed();
|
|
723
|
+
}
|
|
724
|
+
extractCreateSeed() {
|
|
725
|
+
const navigationState = this.router.getCurrentNavigation()?.extras?.state ??
|
|
726
|
+
(typeof history !== 'undefined' ? history.state : undefined);
|
|
727
|
+
const name = navigationState?.['decisionName'];
|
|
728
|
+
const inputVariables = navigationState?.['inputVariables'];
|
|
729
|
+
if (typeof name === 'string' && name) {
|
|
730
|
+
return {
|
|
731
|
+
name,
|
|
732
|
+
inputVariables: Array.isArray(inputVariables)
|
|
733
|
+
? inputVariables
|
|
734
|
+
.filter((variable) => !!variable)
|
|
735
|
+
.map(variable => ({
|
|
736
|
+
label: String(variable['label'] ?? ''),
|
|
737
|
+
expression: String(variable['expression'] ?? ''),
|
|
738
|
+
}))
|
|
739
|
+
: [],
|
|
740
|
+
};
|
|
741
|
+
}
|
|
742
|
+
return null;
|
|
346
743
|
}
|
|
347
744
|
ngOnInit() {
|
|
348
745
|
this.pageTitleService.disableReset();
|
|
349
746
|
}
|
|
350
747
|
ngOnDestroy() {
|
|
748
|
+
this.dmnEditor?.destroy();
|
|
351
749
|
this.pageTitleService.enableReset();
|
|
352
750
|
this.breadcrumbService.clearThirdBreadcrumb();
|
|
353
751
|
this.breadcrumbService.clearFourthBreadcrumb();
|
|
354
752
|
}
|
|
355
753
|
ngAfterViewInit() {
|
|
356
|
-
this.
|
|
357
|
-
this.setTabEvents();
|
|
358
|
-
this.setModelerEvents();
|
|
754
|
+
this.initEditor();
|
|
359
755
|
this.context$.pipe(take(1)).subscribe(context => {
|
|
360
756
|
if (!context)
|
|
361
757
|
return;
|
|
@@ -380,7 +776,7 @@ class DecisionModelerComponent extends PendingChangesComponent {
|
|
|
380
776
|
this._refreshDecisionSelectItems$.next(null);
|
|
381
777
|
}
|
|
382
778
|
deploy() {
|
|
383
|
-
from(this.
|
|
779
|
+
from(this.dmnEditor.saveXML({ format: true }))
|
|
384
780
|
.pipe(map(result => new File([result.xml], this._fileName, { type: 'text/xml' })), switchMap(file => combineLatest([of(file), this.context$])), switchMap(([file, context]) => {
|
|
385
781
|
if (context === 'independent') {
|
|
386
782
|
return this.decisionService.deployDmn(file);
|
|
@@ -399,7 +795,7 @@ class DecisionModelerComponent extends PendingChangesComponent {
|
|
|
399
795
|
.subscribe();
|
|
400
796
|
}
|
|
401
797
|
download() {
|
|
402
|
-
from(this.
|
|
798
|
+
from(this.dmnEditor.saveXML({ format: true }))
|
|
403
799
|
.pipe(map(result => new File([result.xml], 'decision.dmn', { type: 'text/xml' })), tap(file => {
|
|
404
800
|
const link = document.createElement('a');
|
|
405
801
|
link.download = 'diagram.dmn';
|
|
@@ -410,11 +806,54 @@ class DecisionModelerComponent extends PendingChangesComponent {
|
|
|
410
806
|
}))
|
|
411
807
|
.subscribe();
|
|
412
808
|
}
|
|
413
|
-
|
|
414
|
-
this.
|
|
415
|
-
|
|
809
|
+
openEditModal() {
|
|
810
|
+
from(this.dmnEditor.saveXML({ format: true }))
|
|
811
|
+
.pipe(take(1))
|
|
812
|
+
.subscribe(result => this.edit.open(parseDecisionForm(result.xml)));
|
|
813
|
+
}
|
|
814
|
+
onEditDecision(value) {
|
|
815
|
+
from(this.dmnEditor.saveXML({ format: true }))
|
|
816
|
+
.pipe(map(result => updateDmnXml(result.xml, value)), switchMap(xml => this.dmnEditor.importXML(xml)), tap(() => {
|
|
817
|
+
this.setEditor();
|
|
818
|
+
if (value.name)
|
|
819
|
+
this.pageTitleService.setCustomPageTitle(value.name);
|
|
820
|
+
}), catchError(() => {
|
|
821
|
+
this.showNotification('error', 'decisions.loadFailure');
|
|
822
|
+
return of(null);
|
|
823
|
+
}))
|
|
824
|
+
.subscribe();
|
|
825
|
+
}
|
|
826
|
+
onDeleteClick() {
|
|
827
|
+
this.showDeleteModal$.next(true);
|
|
828
|
+
}
|
|
829
|
+
onDeleteConfirm() {
|
|
830
|
+
const decisionKey = this._decisionKey;
|
|
831
|
+
if (!decisionKey)
|
|
416
832
|
return;
|
|
417
|
-
this.
|
|
833
|
+
this.context$
|
|
834
|
+
.pipe(take(1), switchMap(context => {
|
|
835
|
+
if (context === 'buildingBlock') {
|
|
836
|
+
return this.buildingBlockManagementRouteParams$.pipe(take(1), switchMap(params => this.decisionService.deleteBuildingBlockDecisionDefinition(params?.buildingBlockDefinitionKey ?? '', params?.buildingBlockDefinitionVersionTag ?? '', decisionKey)));
|
|
837
|
+
}
|
|
838
|
+
return this.caseManagementRouteParams$.pipe(take(1), switchMap(params => this.decisionService.deleteCaseDecisionDefinition(params?.caseDefinitionKey ?? '', params?.caseDefinitionVersionTag ?? '', decisionKey)));
|
|
839
|
+
}))
|
|
840
|
+
.subscribe({
|
|
841
|
+
next: () => {
|
|
842
|
+
this.navigateBack();
|
|
843
|
+
this.showNotification('success', 'decisions.deleteSuccess');
|
|
844
|
+
},
|
|
845
|
+
error: () => this.showNotification('error', 'decisions.deleteFailure'),
|
|
846
|
+
});
|
|
847
|
+
}
|
|
848
|
+
navigateBack() {
|
|
849
|
+
this.context$.pipe(take(1)).subscribe(context => {
|
|
850
|
+
if (context === 'independent') {
|
|
851
|
+
this.router.navigate(['/decision-tables']);
|
|
852
|
+
}
|
|
853
|
+
else {
|
|
854
|
+
this.router.navigate(['../'], { relativeTo: this.route });
|
|
855
|
+
}
|
|
856
|
+
});
|
|
418
857
|
}
|
|
419
858
|
showNotification(notification, message) {
|
|
420
859
|
if (!notification)
|
|
@@ -425,28 +864,53 @@ class DecisionModelerComponent extends PendingChangesComponent {
|
|
|
425
864
|
title: this.translateService.instant(`interface.${notification}`),
|
|
426
865
|
});
|
|
427
866
|
}
|
|
428
|
-
|
|
429
|
-
|
|
867
|
+
initEditor() {
|
|
868
|
+
// A new decision table is always created in the editable modeler. For existing tables the
|
|
869
|
+
// edit permissions decide whether to render the editable modeler or a read-only viewer.
|
|
870
|
+
if (this.route.snapshot.params?.['id'] === 'create') {
|
|
871
|
+
this.createEditor(false);
|
|
872
|
+
this.loadEmptyDecisionTable();
|
|
873
|
+
return;
|
|
874
|
+
}
|
|
875
|
+
this.hasEditPermissions$
|
|
876
|
+
.pipe(take(1))
|
|
877
|
+
.subscribe(hasEditPermissions => this.createEditor(!hasEditPermissions));
|
|
878
|
+
}
|
|
879
|
+
createEditor(readOnly) {
|
|
430
880
|
this.$container = $('.editor-container');
|
|
431
881
|
this.$tabs = $('.editor-tabs');
|
|
432
|
-
this.
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
882
|
+
this.dmnEditor = readOnly
|
|
883
|
+
? new DmnViewer({
|
|
884
|
+
container: this.$container,
|
|
885
|
+
height: 500,
|
|
886
|
+
width: '100%',
|
|
887
|
+
})
|
|
888
|
+
: new DmnJS({
|
|
889
|
+
container: this.$container,
|
|
890
|
+
height: 500,
|
|
891
|
+
width: '100%',
|
|
892
|
+
keyboard: { bindTo: window },
|
|
893
|
+
});
|
|
894
|
+
this.setTabEvents();
|
|
895
|
+
this.setModelerEvents();
|
|
896
|
+
this._editorReady$.next(true);
|
|
440
897
|
}
|
|
441
898
|
loadEmptyDecisionTable() {
|
|
899
|
+
if (this._createSeed) {
|
|
900
|
+
this._fileName = toDecisionFileName(this._createSeed.name);
|
|
901
|
+
this.pageTitleService.setCustomPageTitle(this._createSeed.name);
|
|
902
|
+
this.loadDecisionXml(createDmnXml(this._createSeed));
|
|
903
|
+
return;
|
|
904
|
+
}
|
|
905
|
+
this._fileName = 'decision.dmn';
|
|
442
906
|
this.loadDecisionXml(EMPTY_DECISION);
|
|
443
907
|
}
|
|
444
908
|
setTabEvents() {
|
|
445
909
|
this.$tabs.delegate('.tab', 'click', async (event) => {
|
|
446
910
|
const index = +event.currentTarget.getAttribute('data-id');
|
|
447
|
-
const view = this.
|
|
911
|
+
const view = this.dmnEditor.getViews()[index];
|
|
448
912
|
try {
|
|
449
|
-
await this.
|
|
913
|
+
await this.dmnEditor.open(view);
|
|
450
914
|
}
|
|
451
915
|
catch (err) {
|
|
452
916
|
console.error('tab open error', err);
|
|
@@ -454,7 +918,7 @@ class DecisionModelerComponent extends PendingChangesComponent {
|
|
|
454
918
|
});
|
|
455
919
|
}
|
|
456
920
|
setModelerEvents() {
|
|
457
|
-
this.
|
|
921
|
+
this.dmnEditor.on('views.changed', event => {
|
|
458
922
|
const { views, activeView } = event;
|
|
459
923
|
this.$tabs.empty();
|
|
460
924
|
views.forEach((v, i) => {
|
|
@@ -465,7 +929,7 @@ class DecisionModelerComponent extends PendingChangesComponent {
|
|
|
465
929
|
});
|
|
466
930
|
}
|
|
467
931
|
loadDecisionXml(decision) {
|
|
468
|
-
from(this.
|
|
932
|
+
from(this.dmnEditor.importXML(decision.dmnXml))
|
|
469
933
|
.pipe(tap(() => this.setEditor()), catchError(() => {
|
|
470
934
|
this.migrateAndLoadDecisionXml(decision);
|
|
471
935
|
return of(null);
|
|
@@ -474,16 +938,16 @@ class DecisionModelerComponent extends PendingChangesComponent {
|
|
|
474
938
|
}
|
|
475
939
|
migrateAndLoadDecisionXml(decision) {
|
|
476
940
|
from(migrateDiagram(decision.dmnXml))
|
|
477
|
-
.pipe(switchMap(xml => this.
|
|
941
|
+
.pipe(switchMap(xml => this.dmnEditor.importXML(xml)), tap(() => this.setEditor()), catchError(() => {
|
|
478
942
|
this.showNotification('error', 'decisions.loadFailure');
|
|
479
943
|
return of(null);
|
|
480
944
|
}))
|
|
481
945
|
.subscribe();
|
|
482
946
|
}
|
|
483
947
|
setEditor() {
|
|
484
|
-
const view = this.
|
|
948
|
+
const view = this.dmnEditor.getActiveView();
|
|
485
949
|
if (view?.type === 'drd') {
|
|
486
|
-
const canvas = this.
|
|
950
|
+
const canvas = this.dmnEditor.getActiveViewer().get('canvas');
|
|
487
951
|
canvas.zoom('fit-viewport');
|
|
488
952
|
}
|
|
489
953
|
}
|
|
@@ -518,8 +982,8 @@ class DecisionModelerComponent extends PendingChangesComponent {
|
|
|
518
982
|
href: routeWithDecisions,
|
|
519
983
|
});
|
|
520
984
|
}
|
|
521
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: DecisionModelerComponent, deps: [{ token: DecisionService }, { token: i2.ActivatedRoute }, { token: i2.Router }, { token: i3.TranslateService }, { token: i4.PageTitleService }, { token: i4.BreadcrumbService }, { token:
|
|
522
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.20", type: DecisionModelerComponent, isStandalone: true, selector: "valtimo-decision-modeler", usesInheritance: 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 *ngIf=\"{\n decisionXml: decisionXml$ | async,\n decisionTitle: decisionTitle$ | async,\n } as obs\"\n fitPage\n [disableOverflow]=\"true\"\n class=\"dmn-editor\"\n>\n <ng-container *ngTemplateOutlet=\"diagram\"></ng-container>\n</div>\n\n<ng-template #diagram>\n <div class=\"editor-parent\">\n <div class=\"editor-container\"></div>\n <div class=\"editor-tabs\"></div>\n </div>\n</ng-template>\n\n<ng-container renderInPageHeader>\n <ng-template>\n <div\n *ngIf=\"{\n selectionId: selectionId$ | async,\n isCreating: isCreating$ | async,\n context: context$ | async,\n compactMode: compactMode$ | async,\n hasEditPermissions: hasEditPermissions$ | async,\n } as obs\"\n class=\"decision-modeler-actions\"\n >\n <ng-container *ngTemplateOutlet=\"versionSelection\"></ng-container>\n\n <button\n *ngIf=\"obs.context === 'case'\"\n cdsButton=\"secondary\"\n [size]=\"obs.compactMode ? 'sm' : 'md'\"\n (click)=\"navigateBack(null)\"\n [attr.data-test-id]=\"testIds.backButton\"\n >\n <svg class=\"cds--btn__icon\" cdsIcon=\"arrow--left\" size=\"16\"></svg>\n\n <span>{{ 'interface.back' | translate }}</span>\n </button>\n\n @if (obs.selectionId && !obs.isCreating) {\n <button\n *ngIf=\"obs.hasEditPermissions\"\n cdsButton=\"primary\"\n (click)=\"deploy()\"\n [size]=\"obs.compactMode ? 'sm' : 'md'\"\n [attr.data-test-id]=\"testIds.deployButton\"\n >\n {{ 'decisions.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 (selected)=\"download()\"\n >{{ 'interface.export' | translate }}\n </v-overflow-menu-option>\n </v-overflow-menu>\n } @else {\n <button class=\"btn btn-success btn-space\" (click)=\"deploy()\">\n <i class=\"icon mdi mdi-upload mr-1\"></i>{{ 'decisions.deploy' | translate }}\n </button>\n }\n </div>\n </ng-template>\n</ng-container>\n\n<ng-template #versionSelection>\n <ng-container\n *ngIf=\"{\n selectItems: (decisionVersionSelectItems$ | async) || [],\n isIndependent: isIndependent$ | async,\n versionSelectionDisabled: versionSelectionDisabled$ | async,\n selectionId: selectionId$ | async,\n } as obs\"\n >\n <v-select\n *ngIf=\"obs.isIndependent\"\n name=\"version\"\n [title]=\"'decisions.version' | translate\"\n [disabled]=\"obs.versionSelectionDisabled\"\n [clearable]=\"false\"\n [loading]=\"obs.selectItems.length === 0\"\n [items]=\"obs.selectItems\"\n [defaultSelectionId]=\"obs.selectionId\"\n [widthInPx]=\"120\"\n (selectedChange)=\"switchVersion($event)\"\n ></v-select>\n </ng-container>\n</ng-template>\n", styles: ["#save-button{position:absolute;bottom:10px;left:10px;background:#fff;border:solid 1px #ccc;border-radius:2px;padding:8px;font-family:Arial,sans-serif;font-weight:700;cursor:default;font-size:14px;color:#444}.dmn-modeler{display:flex;flex-direction:column;width:100%;padding:1rem}.diagram,.diagram-header{border:1px solid #dee2e6}.decision-title{color:#6b6b6b;font-size:1.5rem;margin:0}.fullscreen-toggle{font-size:2rem}.fullscreen-toggle>i{cursor:pointer}.dmn-editor{background-color:var(--cds-layer);outline:1px solid var(--cds-border-subtle);outline-offset:-1px;padding:16px}.decision-modeler-actions{display:flex;width:100%;justify-content:flex-end;align-items:flex-end;gap:16px}\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: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i7.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: i7.AsyncPipe, name: "async" }, { kind: "ngmodule", type: RouterModule }, { kind: "ngmodule", type: ModalModule }, { kind: "ngmodule", type: SelectModule }, { kind: "ngmodule", type: WidgetModule }, { kind: "ngmodule", type: SelectModule$1 }, { kind: "component", type: i4.SelectComponent, selector: "v-select", inputs: ["items", "defaultSelection", "defaultSelectionId", "defaultSelectionIds", "disabled", "dropUp", "invalid", "multiple", "margin", "widthInPx", "notFoundText", "clearAllText", "clearText", "clearable", "name", "title", "titleTranslationKey", "clearSelectionSubject$", "tooltip", "required", "loading", "loadingText", "placeholder", "smallMargin", "carbonTheme", "appendInline", "warn", "warnText", "dataTestId"], outputs: ["selectedChange"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }, { kind: "directive", type: RenderInPageHeaderDirective, selector: "[renderInPageHeader]", inputs: ["fullWidth"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i6$1.Button, selector: "[cdsButton], [ibmButton]", inputs: ["ibmButton", "cdsButton", "size", "skeleton", "iconOnly", "isExpressive"] }, { kind: "ngmodule", type: IconModule }, { kind: "directive", type: i6$1.IconDirective, selector: "[cdsIcon], [ibmIcon]", inputs: ["ibmIcon", "cdsIcon", "size", "title", "ariaLabel", "ariaLabelledBy", "ariaHidden", "isFocusable"] }, { kind: "directive", type: FitPageDirective, selector: "[fitPage]", inputs: ["spaceAdjustment", "fitPageDisabled", "disableOverflow"] }, { 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"] }] }); }
|
|
985
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: DecisionModelerComponent, deps: [{ token: DecisionService }, { token: i2.ActivatedRoute }, { token: i2.Router }, { token: i3.TranslateService }, { token: i4$1.PageTitleService }, { token: i4$1.BreadcrumbService }, { token: i4.IconService }, { token: i4$1.PageHeaderService }, { token: i6.GlobalNotificationService }, { token: i6.EditPermissionsService }, { token: i6.DraftVersionService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
986
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.20", type: DecisionModelerComponent, isStandalone: true, selector: "valtimo-decision-modeler", viewQueries: [{ propertyName: "edit", first: true, predicate: ["decisionEdit"], descendants: true }], usesInheritance: 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 *ngIf=\"{\n decisionXml: decisionXml$ | async,\n decisionTitle: decisionTitle$ | async,\n } as obs\"\n fitPage\n [disableOverflow]=\"true\"\n class=\"dmn-editor\"\n>\n <ng-container *ngTemplateOutlet=\"diagram\"></ng-container>\n</div>\n\n<ng-template #diagram>\n <div class=\"editor-parent\">\n <div class=\"editor-container\"></div>\n <div class=\"editor-tabs\"></div>\n </div>\n</ng-template>\n\n<ng-container renderInPageHeader>\n <ng-template>\n <div\n *ngIf=\"{\n selectionId: selectionId$ | async,\n isCreating: isCreating$ | async,\n context: context$ | async,\n compactMode: compactMode$ | async,\n hasEditPermissions: hasEditPermissions$ | async,\n readOnly: readOnly$ | async,\n } as obs\"\n class=\"decision-modeler-actions\"\n >\n <cds-tag *ngIf=\"obs.readOnly\" type=\"blue\" [attr.data-test-id]=\"testIds.readOnlyTag\">{{\n 'decisions.readOnly' | translate\n }}</cds-tag>\n\n <ng-container *ngTemplateOutlet=\"versionSelection\"></ng-container>\n\n <button\n *ngIf=\"obs.context === 'case' || obs.isCreating\"\n cdsButton=\"secondary\"\n [size]=\"obs.compactMode ? 'sm' : 'md'\"\n (click)=\"navigateBack()\"\n [attr.data-test-id]=\"testIds.backButton\"\n >\n <svg class=\"cds--btn__icon\" cdsIcon=\"arrow--left\" size=\"16\"></svg>\n\n <span>{{ 'interface.back' | translate }}</span>\n </button>\n\n @if (obs.selectionId && !obs.isCreating) {\n <button\n cdsButton=\"primary\"\n [disabled]=\"!obs.hasEditPermissions\"\n (click)=\"deploy()\"\n [size]=\"obs.compactMode ? 'sm' : 'md'\"\n [attr.data-test-id]=\"testIds.deployButton\"\n >\n {{ 'decisions.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 [disabled]=\"!obs.hasEditPermissions\" (selected)=\"openEditModal()\"\n >{{ 'interface.edit' | translate }}\n </v-overflow-menu-option>\n <v-overflow-menu-option (selected)=\"download()\"\n >{{ 'interface.export' | translate }}\n </v-overflow-menu-option>\n <v-overflow-menu-option\n [disabled]=\"!obs.hasEditPermissions || obs.context === 'independent'\"\n type=\"danger\"\n (selected)=\"onDeleteClick()\"\n >{{ 'interface.delete' | translate }}\n </v-overflow-menu-option>\n </v-overflow-menu>\n } @else {\n <button\n cdsButton=\"primary\"\n [disabled]=\"!obs.hasEditPermissions\"\n (click)=\"deploy()\"\n [size]=\"obs.compactMode ? 'sm' : 'md'\"\n [attr.data-test-id]=\"testIds.deployButton\"\n >\n {{ 'decisions.deploy' | translate }}\n\n <svg class=\"cds--btn__icon\" cdsIcon=\"deploy\" size=\"16\"></svg>\n </button>\n }\n </div>\n </ng-template>\n</ng-container>\n\n<ng-template #versionSelection>\n <ng-container\n *ngIf=\"{\n selectItems: (decisionVersionSelectItems$ | async) || [],\n isIndependent: isIndependent$ | async,\n versionSelectionDisabled: versionSelectionDisabled$ | async,\n selectionId: selectionId$ | async,\n } as obs\"\n >\n <v-select\n *ngIf=\"obs.isIndependent\"\n name=\"version\"\n [title]=\"'decisions.version' | translate\"\n [disabled]=\"obs.versionSelectionDisabled\"\n [clearable]=\"false\"\n [loading]=\"obs.selectItems.length === 0\"\n [items]=\"obs.selectItems\"\n [defaultSelectionId]=\"obs.selectionId\"\n [widthInPx]=\"120\"\n (selectedChange)=\"switchVersion($event)\"\n ></v-select>\n </ng-container>\n</ng-template>\n\n<valtimo-decision-form-modal\n #decisionEdit\n titleKey=\"decisions.editModal.title\"\n submitKey=\"interface.save\"\n (submitEvent)=\"onEditDecision($event)\"\n></valtimo-decision-form-modal>\n\n<valtimo-confirmation-modal\n confirmButtonTextTranslationKey=\"interface.delete\"\n confirmButtonType=\"danger\"\n contentTranslationKey=\"decisions.deleteModal.content\"\n [showModalSubject$]=\"showDeleteModal$\"\n titleTranslationKey=\"decisions.deleteModal.title\"\n (confirmEvent)=\"onDeleteConfirm()\"\n></valtimo-confirmation-modal>\n", styles: ["#save-button{position:absolute;bottom:10px;left:10px;background:#fff;border:solid 1px #ccc;border-radius:2px;padding:8px;font-family:Arial,sans-serif;font-weight:700;cursor:default;font-size:14px;color:#444}.dmn-modeler{display:flex;flex-direction:column;width:100%;padding:1rem}.diagram,.diagram-header{border:1px solid #dee2e6}.decision-title{color:#6b6b6b;font-size:1.5rem;margin:0}.fullscreen-toggle{font-size:2rem}.fullscreen-toggle>i{cursor:pointer}.dmn-editor{background-color:var(--cds-layer);outline:1px solid var(--cds-border-subtle);outline-offset:-1px;padding:16px}.decision-modeler-actions{display:flex;width:100%;justify-content:flex-end;align-items:flex-end;gap:16px}\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: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i7.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: i7.AsyncPipe, name: "async" }, { kind: "ngmodule", type: RouterModule }, { kind: "ngmodule", type: ModalModule }, { kind: "ngmodule", type: SelectModule }, { kind: "ngmodule", type: WidgetModule }, { kind: "ngmodule", type: SelectModule$1 }, { kind: "component", type: i4$1.SelectComponent, selector: "v-select", inputs: ["items", "defaultSelection", "defaultSelectionId", "defaultSelectionIds", "disabled", "dropUp", "invalid", "multiple", "margin", "widthInPx", "notFoundText", "clearAllText", "clearText", "clearable", "name", "title", "titleTranslationKey", "clearSelectionSubject$", "tooltip", "required", "loading", "loadingText", "placeholder", "smallMargin", "carbonTheme", "appendInline", "warn", "warnText", "dataTestId"], outputs: ["selectedChange"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }, { kind: "directive", type: RenderInPageHeaderDirective, selector: "[renderInPageHeader]", inputs: ["fullWidth"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i4.Button, selector: "[cdsButton], [ibmButton]", inputs: ["ibmButton", "cdsButton", "size", "skeleton", "iconOnly", "isExpressive"] }, { kind: "ngmodule", type: IconModule }, { kind: "directive", type: i4.IconDirective, selector: "[cdsIcon], [ibmIcon]", inputs: ["ibmIcon", "cdsIcon", "size", "title", "ariaLabel", "ariaLabelledBy", "ariaHidden", "isFocusable"] }, { kind: "ngmodule", type: TagModule }, { kind: "component", type: i4.Tag, selector: "cds-tag, ibm-tag", inputs: ["type", "size", "class", "skeleton"] }, { kind: "directive", type: FitPageDirective, selector: "[fitPage]", inputs: ["spaceAdjustment", "fitPageDisabled", "disableOverflow", "bottomMargin"] }, { 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: "component", type: DecisionFormModalComponent, selector: "valtimo-decision-form-modal", inputs: ["titleKey", "submitKey"], outputs: ["submitEvent"] }, { kind: "ngmodule", type: ConfirmationModalModule }, { kind: "component", type: i4$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"] }] }); }
|
|
523
987
|
}
|
|
524
988
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: DecisionModelerComponent, decorators: [{
|
|
525
989
|
type: Component,
|
|
@@ -534,12 +998,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImpo
|
|
|
534
998
|
RenderInPageHeaderDirective,
|
|
535
999
|
ButtonModule,
|
|
536
1000
|
IconModule,
|
|
1001
|
+
TagModule,
|
|
537
1002
|
FitPageDirective,
|
|
538
1003
|
OverflowMenuComponent,
|
|
539
1004
|
OverflowMenuOptionComponent,
|
|
540
1005
|
OverflowMenuTriggerComponent,
|
|
541
|
-
|
|
542
|
-
|
|
1006
|
+
DecisionFormModalComponent,
|
|
1007
|
+
ConfirmationModalModule,
|
|
1008
|
+
], 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 *ngIf=\"{\n decisionXml: decisionXml$ | async,\n decisionTitle: decisionTitle$ | async,\n } as obs\"\n fitPage\n [disableOverflow]=\"true\"\n class=\"dmn-editor\"\n>\n <ng-container *ngTemplateOutlet=\"diagram\"></ng-container>\n</div>\n\n<ng-template #diagram>\n <div class=\"editor-parent\">\n <div class=\"editor-container\"></div>\n <div class=\"editor-tabs\"></div>\n </div>\n</ng-template>\n\n<ng-container renderInPageHeader>\n <ng-template>\n <div\n *ngIf=\"{\n selectionId: selectionId$ | async,\n isCreating: isCreating$ | async,\n context: context$ | async,\n compactMode: compactMode$ | async,\n hasEditPermissions: hasEditPermissions$ | async,\n readOnly: readOnly$ | async,\n } as obs\"\n class=\"decision-modeler-actions\"\n >\n <cds-tag *ngIf=\"obs.readOnly\" type=\"blue\" [attr.data-test-id]=\"testIds.readOnlyTag\">{{\n 'decisions.readOnly' | translate\n }}</cds-tag>\n\n <ng-container *ngTemplateOutlet=\"versionSelection\"></ng-container>\n\n <button\n *ngIf=\"obs.context === 'case' || obs.isCreating\"\n cdsButton=\"secondary\"\n [size]=\"obs.compactMode ? 'sm' : 'md'\"\n (click)=\"navigateBack()\"\n [attr.data-test-id]=\"testIds.backButton\"\n >\n <svg class=\"cds--btn__icon\" cdsIcon=\"arrow--left\" size=\"16\"></svg>\n\n <span>{{ 'interface.back' | translate }}</span>\n </button>\n\n @if (obs.selectionId && !obs.isCreating) {\n <button\n cdsButton=\"primary\"\n [disabled]=\"!obs.hasEditPermissions\"\n (click)=\"deploy()\"\n [size]=\"obs.compactMode ? 'sm' : 'md'\"\n [attr.data-test-id]=\"testIds.deployButton\"\n >\n {{ 'decisions.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 [disabled]=\"!obs.hasEditPermissions\" (selected)=\"openEditModal()\"\n >{{ 'interface.edit' | translate }}\n </v-overflow-menu-option>\n <v-overflow-menu-option (selected)=\"download()\"\n >{{ 'interface.export' | translate }}\n </v-overflow-menu-option>\n <v-overflow-menu-option\n [disabled]=\"!obs.hasEditPermissions || obs.context === 'independent'\"\n type=\"danger\"\n (selected)=\"onDeleteClick()\"\n >{{ 'interface.delete' | translate }}\n </v-overflow-menu-option>\n </v-overflow-menu>\n } @else {\n <button\n cdsButton=\"primary\"\n [disabled]=\"!obs.hasEditPermissions\"\n (click)=\"deploy()\"\n [size]=\"obs.compactMode ? 'sm' : 'md'\"\n [attr.data-test-id]=\"testIds.deployButton\"\n >\n {{ 'decisions.deploy' | translate }}\n\n <svg class=\"cds--btn__icon\" cdsIcon=\"deploy\" size=\"16\"></svg>\n </button>\n }\n </div>\n </ng-template>\n</ng-container>\n\n<ng-template #versionSelection>\n <ng-container\n *ngIf=\"{\n selectItems: (decisionVersionSelectItems$ | async) || [],\n isIndependent: isIndependent$ | async,\n versionSelectionDisabled: versionSelectionDisabled$ | async,\n selectionId: selectionId$ | async,\n } as obs\"\n >\n <v-select\n *ngIf=\"obs.isIndependent\"\n name=\"version\"\n [title]=\"'decisions.version' | translate\"\n [disabled]=\"obs.versionSelectionDisabled\"\n [clearable]=\"false\"\n [loading]=\"obs.selectItems.length === 0\"\n [items]=\"obs.selectItems\"\n [defaultSelectionId]=\"obs.selectionId\"\n [widthInPx]=\"120\"\n (selectedChange)=\"switchVersion($event)\"\n ></v-select>\n </ng-container>\n</ng-template>\n\n<valtimo-decision-form-modal\n #decisionEdit\n titleKey=\"decisions.editModal.title\"\n submitKey=\"interface.save\"\n (submitEvent)=\"onEditDecision($event)\"\n></valtimo-decision-form-modal>\n\n<valtimo-confirmation-modal\n confirmButtonTextTranslationKey=\"interface.delete\"\n confirmButtonType=\"danger\"\n contentTranslationKey=\"decisions.deleteModal.content\"\n [showModalSubject$]=\"showDeleteModal$\"\n titleTranslationKey=\"decisions.deleteModal.title\"\n (confirmEvent)=\"onDeleteConfirm()\"\n></valtimo-confirmation-modal>\n", styles: ["#save-button{position:absolute;bottom:10px;left:10px;background:#fff;border:solid 1px #ccc;border-radius:2px;padding:8px;font-family:Arial,sans-serif;font-weight:700;cursor:default;font-size:14px;color:#444}.dmn-modeler{display:flex;flex-direction:column;width:100%;padding:1rem}.diagram,.diagram-header{border:1px solid #dee2e6}.decision-title{color:#6b6b6b;font-size:1.5rem;margin:0}.fullscreen-toggle{font-size:2rem}.fullscreen-toggle>i{cursor:pointer}.dmn-editor{background-color:var(--cds-layer);outline:1px solid var(--cds-border-subtle);outline-offset:-1px;padding:16px}.decision-modeler-actions{display:flex;width:100%;justify-content:flex-end;align-items:flex-end;gap:16px}\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"] }]
|
|
1009
|
+
}], ctorParameters: () => [{ type: DecisionService }, { type: i2.ActivatedRoute }, { type: i2.Router }, { type: i3.TranslateService }, { type: i4$1.PageTitleService }, { type: i4$1.BreadcrumbService }, { type: i4.IconService }, { type: i4$1.PageHeaderService }, { type: i6.GlobalNotificationService }, { type: i6.EditPermissionsService }, { type: i6.DraftVersionService }], propDecorators: { edit: [{
|
|
1010
|
+
type: ViewChild,
|
|
1011
|
+
args: ['decisionEdit']
|
|
1012
|
+
}] } });
|
|
543
1013
|
|
|
544
1014
|
/*
|
|
545
1015
|
* Copyright 2015-2025 Ritense BV, the Netherlands.
|
|
@@ -562,7 +1032,7 @@ class DecisionDisplayComponent {
|
|
|
562
1032
|
this.route = route;
|
|
563
1033
|
}
|
|
564
1034
|
ngOnInit() {
|
|
565
|
-
this.viewer = new DmnViewer({
|
|
1035
|
+
this.viewer = new DmnViewer$1({
|
|
566
1036
|
container: '#canvas',
|
|
567
1037
|
});
|
|
568
1038
|
this.decisionId = this.route.snapshot.paramMap.get('id');
|
|
@@ -698,8 +1168,8 @@ class DecisionDeployComponent {
|
|
|
698
1168
|
closeModal() {
|
|
699
1169
|
this.modalOpen$.next(false);
|
|
700
1170
|
}
|
|
701
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: DecisionDeployComponent, deps: [{ token: DecisionService }, { token: DecisionStateService }, { token: i2.ActivatedRoute }, { token:
|
|
702
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.20", type: DecisionDeployComponent, isStandalone: true, selector: "valtimo-decision-deploy", outputs: { deploySuccessful: "deploySuccessful" }, 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<cds-modal showFooter=\"true\" valtimoCdsModal [open]=\"modalOpen$ | async\" (close)=\"closeModal()\">\n <cds-modal-header showCloseButton=\"true\" (closeSelect)=\"closeModal()\">\n <h3 cdsModalHeaderHeading>{{ 'decisions.upload.title' | translate }}</h3>\n </cds-modal-header>\n\n <section cdsModalContent [cdsLayer]=\"1\" [formGroup]=\"form\">\n <cds-file-uploader\n [accept]=\"ACCEPTED_FILES\"\n [multiple]=\"false\"\n buttonType=\"primary\"\n [title]=\"'decisions.upload.fileUploaderTitle' | translate\"\n [description]=\"'decisions.upload.fileUploaderDescription' | translate\"\n [buttonText]=\"'decisions.upload.fileUploaderButton' | translate\"\n formControlName=\"file\"\n >\n </cds-file-uploader>\n </section>\n\n <cds-modal-footer>\n <button cdsButton=\"secondary\" (click)=\"closeModal()\">\n {{ 'interface.cancel' | translate }}\n </button>\n\n <button\n cdsButton=\"primary\"\n [disabled]=\"!selectedDmnFile\"\n (click)=\"deployDmn()\"\n [attr.data-test-id]=\"testIds.submitButton\"\n >\n {{ 'interface.upload' | translate }}\n </button>\n </cds-modal-footer>\n</cds-modal>\n", styles: ["/*!\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: "pipe", type: i7.AsyncPipe, name: "async" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type:
|
|
1171
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: DecisionDeployComponent, deps: [{ token: DecisionService }, { token: DecisionStateService }, { token: i2.ActivatedRoute }, { token: i1$1.FormBuilder }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1172
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.20", type: DecisionDeployComponent, isStandalone: true, selector: "valtimo-decision-deploy", outputs: { deploySuccessful: "deploySuccessful" }, 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<cds-modal showFooter=\"true\" valtimoCdsModal [open]=\"modalOpen$ | async\" (close)=\"closeModal()\">\n <cds-modal-header showCloseButton=\"true\" (closeSelect)=\"closeModal()\">\n <h3 cdsModalHeaderHeading>{{ 'decisions.upload.title' | translate }}</h3>\n </cds-modal-header>\n\n <section cdsModalContent [cdsLayer]=\"1\" [formGroup]=\"form\">\n <cds-file-uploader\n [accept]=\"ACCEPTED_FILES\"\n [multiple]=\"false\"\n buttonType=\"primary\"\n [title]=\"'decisions.upload.fileUploaderTitle' | translate\"\n [description]=\"'decisions.upload.fileUploaderDescription' | translate\"\n [buttonText]=\"'decisions.upload.fileUploaderButton' | translate\"\n formControlName=\"file\"\n >\n </cds-file-uploader>\n </section>\n\n <cds-modal-footer>\n <button cdsButton=\"secondary\" (click)=\"closeModal()\">\n {{ 'interface.cancel' | translate }}\n </button>\n\n <button\n cdsButton=\"primary\"\n [disabled]=\"!selectedDmnFile\"\n (click)=\"deployDmn()\"\n [attr.data-test-id]=\"testIds.submitButton\"\n >\n {{ 'interface.upload' | translate }}\n </button>\n </cds-modal-footer>\n</cds-modal>\n", styles: ["/*!\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: "pipe", type: i7.AsyncPipe, name: "async" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: ModalModule }, { kind: "component", type: i4.Modal, selector: "cds-modal, ibm-modal", inputs: ["size", "theme", "ariaLabel", "open", "trigger", "hasScrollingContent"], outputs: ["overlaySelected", "close"] }, { kind: "component", type: i4.ModalHeader, selector: "cds-modal-header, ibm-modal-header", inputs: ["theme", "closeLabel", "showCloseButton"], outputs: ["closeSelect"] }, { kind: "component", type: i4.ModalFooter, selector: "cds-modal-footer, ibm-modal-footer" }, { kind: "directive", type: i4.ModalContent, selector: "[cdsModalContent], [ibmModalContent]", inputs: ["hasForm"] }, { kind: "directive", type: i4.ModalHeaderHeading, selector: "[cdsModalHeaderHeading], [ibmModalHeaderHeading]" }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i4.Button, selector: "[cdsButton], [ibmButton]", inputs: ["ibmButton", "cdsButton", "size", "skeleton", "iconOnly", "isExpressive"] }, { kind: "ngmodule", type: LayerModule }, { kind: "directive", type: i4.LayerDirective, selector: "[cdsLayer], [ibmLayer]", inputs: ["ibmLayer", "cdsLayer"], exportAs: ["layer"] }, { kind: "ngmodule", type: FileUploaderModule }, { kind: "component", type: i4.FileUploader, selector: "cds-file-uploader, ibm-file-uploader", inputs: ["buttonText", "buttonType", "title", "description", "accept", "multiple", "skeleton", "size", "fileItemSize", "drop", "dropText", "fileUploaderId", "files", "disabled"], outputs: ["filesChange"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }] }); }
|
|
703
1173
|
}
|
|
704
1174
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: DecisionDeployComponent, decorators: [{
|
|
705
1175
|
type: Component,
|
|
@@ -713,7 +1183,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImpo
|
|
|
713
1183
|
FileUploaderModule,
|
|
714
1184
|
ReactiveFormsModule,
|
|
715
1185
|
], 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<cds-modal showFooter=\"true\" valtimoCdsModal [open]=\"modalOpen$ | async\" (close)=\"closeModal()\">\n <cds-modal-header showCloseButton=\"true\" (closeSelect)=\"closeModal()\">\n <h3 cdsModalHeaderHeading>{{ 'decisions.upload.title' | translate }}</h3>\n </cds-modal-header>\n\n <section cdsModalContent [cdsLayer]=\"1\" [formGroup]=\"form\">\n <cds-file-uploader\n [accept]=\"ACCEPTED_FILES\"\n [multiple]=\"false\"\n buttonType=\"primary\"\n [title]=\"'decisions.upload.fileUploaderTitle' | translate\"\n [description]=\"'decisions.upload.fileUploaderDescription' | translate\"\n [buttonText]=\"'decisions.upload.fileUploaderButton' | translate\"\n formControlName=\"file\"\n >\n </cds-file-uploader>\n </section>\n\n <cds-modal-footer>\n <button cdsButton=\"secondary\" (click)=\"closeModal()\">\n {{ 'interface.cancel' | translate }}\n </button>\n\n <button\n cdsButton=\"primary\"\n [disabled]=\"!selectedDmnFile\"\n (click)=\"deployDmn()\"\n [attr.data-test-id]=\"testIds.submitButton\"\n >\n {{ 'interface.upload' | translate }}\n </button>\n </cds-modal-footer>\n</cds-modal>\n", styles: ["/*!\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"] }]
|
|
716
|
-
}], ctorParameters: () => [{ type: DecisionService }, { type: DecisionStateService }, { type: i2.ActivatedRoute }, { type:
|
|
1186
|
+
}], ctorParameters: () => [{ type: DecisionService }, { type: DecisionStateService }, { type: i2.ActivatedRoute }, { type: i1$1.FormBuilder }], propDecorators: { deploySuccessful: [{
|
|
717
1187
|
type: Output
|
|
718
1188
|
}] } });
|
|
719
1189
|
|
|
@@ -733,22 +1203,37 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImpo
|
|
|
733
1203
|
* limitations under the License.
|
|
734
1204
|
*/
|
|
735
1205
|
class DecisionListComponent {
|
|
736
|
-
constructor(decisionService, iconService, router,
|
|
1206
|
+
constructor(decisionService, iconService, router, stateService, route, cdr, editPermissionsService, notificationService, translateService) {
|
|
737
1207
|
this.decisionService = decisionService;
|
|
738
1208
|
this.iconService = iconService;
|
|
739
1209
|
this.router = router;
|
|
740
|
-
this.configService = configService;
|
|
741
1210
|
this.stateService = stateService;
|
|
742
1211
|
this.route = route;
|
|
743
1212
|
this.cdr = cdr;
|
|
744
1213
|
this.editPermissionsService = editPermissionsService;
|
|
1214
|
+
this.notificationService = notificationService;
|
|
1215
|
+
this.translateService = translateService;
|
|
745
1216
|
this.fields = [
|
|
746
1217
|
{ key: 'key', label: 'Key' },
|
|
747
1218
|
{ key: 'name', label: 'Name' },
|
|
748
1219
|
{ key: 'version', label: 'Version' },
|
|
749
1220
|
];
|
|
1221
|
+
this.ACTION_ITEMS = [
|
|
1222
|
+
{
|
|
1223
|
+
label: 'interface.edit',
|
|
1224
|
+
callback: this.openEditModal.bind(this),
|
|
1225
|
+
type: 'normal',
|
|
1226
|
+
disabled$: () => this.hasEditPermissions$.pipe(map(canEdit => !canEdit)),
|
|
1227
|
+
},
|
|
1228
|
+
{
|
|
1229
|
+
label: 'interface.delete',
|
|
1230
|
+
callback: this.onDeleteClick.bind(this),
|
|
1231
|
+
type: 'danger',
|
|
1232
|
+
disabled$: () => this.hasEditPermissions$.pipe(map(canEdit => !canEdit || this._context !== 'case')),
|
|
1233
|
+
},
|
|
1234
|
+
];
|
|
1235
|
+
this.showDeleteModal$ = new BehaviorSubject(false);
|
|
750
1236
|
this.loading$ = new BehaviorSubject(true);
|
|
751
|
-
this.experimentalEditing$ = this.configService.getFeatureToggleObservable('experimentalDmnEditing');
|
|
752
1237
|
this.testIds = DECISION_LIST_TEST_IDS;
|
|
753
1238
|
this.caseManagementRouteParams$ = getCaseManagementRouteParams(this.route);
|
|
754
1239
|
this.buildingBlockManagementRouteParams$ = getBuildingBlockManagementRouteParams(this.route);
|
|
@@ -760,7 +1245,7 @@ class DecisionListComponent {
|
|
|
760
1245
|
if (context === 'buildingBlock') {
|
|
761
1246
|
return this.buildingBlockManagementRouteParams$.pipe(switchMap(params => this.decisionService.listBuildingBlockDecisionDefinitions(params.buildingBlockDefinitionKey, params.buildingBlockDefinitionVersionTag)));
|
|
762
1247
|
}
|
|
763
|
-
return this.decisionService.
|
|
1248
|
+
return this.decisionService.getUnlinkedDecisions();
|
|
764
1249
|
}), map(filterLatestDecisionVersions), tap(() => {
|
|
765
1250
|
this.loading$.next(false);
|
|
766
1251
|
this.cdr.detectChanges();
|
|
@@ -771,30 +1256,110 @@ class DecisionListComponent {
|
|
|
771
1256
|
]).pipe(switchMap(([params, context]) => {
|
|
772
1257
|
return this.editPermissionsService.hasPermissionsToEditBasedOnContext(params, context);
|
|
773
1258
|
}));
|
|
774
|
-
this.
|
|
1259
|
+
this._editDecision = null;
|
|
1260
|
+
this._editXml = null;
|
|
1261
|
+
this._decisionToDelete = null;
|
|
1262
|
+
this._context = null;
|
|
1263
|
+
this.iconService.registerAll([Upload16, Add16]);
|
|
1264
|
+
this.context$.pipe(take(1)).subscribe(context => (this._context = context));
|
|
775
1265
|
}
|
|
776
1266
|
viewDecisionTable(decision) {
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
.subscribe(([context, experimentalEditing]) => {
|
|
780
|
-
if (context === 'independent') {
|
|
781
|
-
const basePath = experimentalEditing ? '/decision-tables/edit/' : '/decision-tables/';
|
|
782
|
-
this.router.navigate([basePath + decision.id]);
|
|
783
|
-
}
|
|
784
|
-
else if (context === 'buildingBlock') {
|
|
1267
|
+
this.context$.pipe(take(1)).subscribe(context => {
|
|
1268
|
+
if (context === 'buildingBlock') {
|
|
785
1269
|
this.buildingBlockManagementRouteParams$.pipe(take(1)).subscribe(params => {
|
|
786
1270
|
this.router.navigateByUrl(`building-block-management/building-block/${params.buildingBlockDefinitionKey}/version/${params.buildingBlockDefinitionVersionTag}/decisions/${decision.id}`);
|
|
787
1271
|
});
|
|
788
1272
|
}
|
|
789
|
-
else {
|
|
1273
|
+
else if (context === 'case') {
|
|
790
1274
|
this.caseManagementRouteParams$.pipe(take(1)).subscribe(params => {
|
|
791
1275
|
this.router.navigateByUrl(`case-management/case/${params.caseDefinitionKey}/version/${params.caseDefinitionVersionTag}/decisions/${decision.id}`);
|
|
792
1276
|
});
|
|
793
1277
|
}
|
|
1278
|
+
else {
|
|
1279
|
+
this.router.navigate(['/decision-tables/edit/' + decision.id]);
|
|
1280
|
+
}
|
|
1281
|
+
});
|
|
1282
|
+
}
|
|
1283
|
+
onCreateDecision(value) {
|
|
1284
|
+
const state = { decisionName: value.name, inputVariables: value.inputVariables };
|
|
1285
|
+
this.context$.pipe(take(1)).subscribe(context => {
|
|
1286
|
+
if (context === 'buildingBlock') {
|
|
1287
|
+
this.buildingBlockManagementRouteParams$.pipe(take(1)).subscribe(params => {
|
|
1288
|
+
this.router.navigateByUrl(`building-block-management/building-block/${params.buildingBlockDefinitionKey}/version/${params.buildingBlockDefinitionVersionTag}/decisions/create`, { state });
|
|
1289
|
+
});
|
|
1290
|
+
}
|
|
1291
|
+
else if (context === 'case') {
|
|
1292
|
+
this.caseManagementRouteParams$.pipe(take(1)).subscribe(params => {
|
|
1293
|
+
this.router.navigateByUrl(`case-management/case/${params.caseDefinitionKey}/version/${params.caseDefinitionVersionTag}/decisions/create`, { state });
|
|
1294
|
+
});
|
|
1295
|
+
}
|
|
1296
|
+
else {
|
|
1297
|
+
this.router.navigate(['/decision-tables/edit/create'], { state });
|
|
1298
|
+
}
|
|
1299
|
+
});
|
|
1300
|
+
}
|
|
1301
|
+
openEditModal(decision) {
|
|
1302
|
+
this.decisionService
|
|
1303
|
+
.getDecisionXml(decision.id)
|
|
1304
|
+
.pipe(take(1))
|
|
1305
|
+
.subscribe(xml => {
|
|
1306
|
+
this._editDecision = decision;
|
|
1307
|
+
this._editXml = xml.dmnXml;
|
|
1308
|
+
this.edit.open(parseDecisionForm(xml.dmnXml));
|
|
1309
|
+
});
|
|
1310
|
+
}
|
|
1311
|
+
onEditDecision(value) {
|
|
1312
|
+
if (!this._editXml || !this._editDecision)
|
|
1313
|
+
return;
|
|
1314
|
+
const patchedXml = updateDmnXml(this._editXml, value);
|
|
1315
|
+
const fileName = this._editDecision.resource || toDecisionFileName(this._editDecision.key);
|
|
1316
|
+
const file = new File([patchedXml], fileName, { type: 'text/xml' });
|
|
1317
|
+
this.deployFileForContext(file).subscribe({
|
|
1318
|
+
next: () => {
|
|
1319
|
+
this.showNotification('success', 'decisions.deploySuccess');
|
|
1320
|
+
this.stateService.refreshDecisions();
|
|
1321
|
+
},
|
|
1322
|
+
error: () => this.showNotification('error', 'decisions.deployFailure'),
|
|
1323
|
+
});
|
|
1324
|
+
}
|
|
1325
|
+
onDeleteClick(decision) {
|
|
1326
|
+
this._decisionToDelete = decision;
|
|
1327
|
+
this.showDeleteModal$.next(true);
|
|
1328
|
+
}
|
|
1329
|
+
onDeleteConfirm() {
|
|
1330
|
+
if (!this._decisionToDelete)
|
|
1331
|
+
return;
|
|
1332
|
+
const decisionKey = this._decisionToDelete.key;
|
|
1333
|
+
this.caseManagementRouteParams$
|
|
1334
|
+
.pipe(take(1), switchMap(params => this.decisionService.deleteCaseDecisionDefinition(params.caseDefinitionKey, params.caseDefinitionVersionTag, decisionKey)))
|
|
1335
|
+
.subscribe({
|
|
1336
|
+
next: () => {
|
|
1337
|
+
this.showNotification('success', 'decisions.deleteSuccess');
|
|
1338
|
+
this.stateService.refreshDecisions();
|
|
1339
|
+
},
|
|
1340
|
+
error: () => this.showNotification('error', 'decisions.deleteFailure'),
|
|
794
1341
|
});
|
|
795
1342
|
}
|
|
796
|
-
|
|
797
|
-
|
|
1343
|
+
deployFileForContext(file) {
|
|
1344
|
+
return this.context$.pipe(take(1), switchMap(context => {
|
|
1345
|
+
if (context === 'case') {
|
|
1346
|
+
return this.caseManagementRouteParams$.pipe(take(1), switchMap(params => this.decisionService.deployCaseDecisionDefinition(params.caseDefinitionKey, params.caseDefinitionVersionTag, file)));
|
|
1347
|
+
}
|
|
1348
|
+
if (context === 'buildingBlock') {
|
|
1349
|
+
return this.buildingBlockManagementRouteParams$.pipe(take(1), switchMap(params => this.decisionService.deployBuildingBlockDecisionDefinition(params.buildingBlockDefinitionKey, params.buildingBlockDefinitionVersionTag, file)));
|
|
1350
|
+
}
|
|
1351
|
+
return this.decisionService.deployDmn(file);
|
|
1352
|
+
}));
|
|
1353
|
+
}
|
|
1354
|
+
showNotification(type, message) {
|
|
1355
|
+
this.notificationService.showToast({
|
|
1356
|
+
caption: this.translateService.instant(message),
|
|
1357
|
+
type,
|
|
1358
|
+
title: this.translateService.instant(`interface.${type}`),
|
|
1359
|
+
});
|
|
1360
|
+
}
|
|
1361
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: DecisionListComponent, deps: [{ token: DecisionService }, { token: i4.IconService }, { token: i2.Router }, { token: DecisionStateService }, { token: i2.ActivatedRoute }, { token: i0.ChangeDetectorRef }, { token: i6.EditPermissionsService }, { token: i6.GlobalNotificationService }, { token: i3.TranslateService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1362
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.20", type: DecisionListComponent, isStandalone: true, selector: "valtimo-decision-list", viewQueries: [{ propertyName: "deploy", first: true, predicate: ["decisionDeploy"], descendants: true }, { propertyName: "create", first: true, predicate: ["decisionCreate"], descendants: true }, { propertyName: "edit", first: true, predicate: ["decisionEdit"], 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<valtimo-carbon-list\n [items]=\"(decisionsLatestVersions$ | async) || []\"\n [loading]=\"loading$ | async\"\n [fields]=\"fields\"\n [actionItems]=\"ACTION_ITEMS\"\n (rowClicked)=\"viewDecisionTable($event)\"\n [header]=\"false\"\n [isSearchable]=\"true\"\n>\n <ng-container carbonToolbarContent>\n <ng-container *ngIf=\"{canEdit: hasEditPermissions$ | async} as obs\">\n <button\n cdsButton=\"ghost\"\n iconOnly=\"true\"\n [disabled]=\"!obs.canEdit\"\n (click)=\"this.deploy.openModal()\"\n [attr.data-test-id]=\"testIds.uploadButton\"\n >\n <svg cdsIcon=\"upload\" size=\"16\"></svg>\n </button>\n\n <button\n cdsButton=\"primary\"\n [disabled]=\"!obs.canEdit\"\n (click)=\"this.create.openModal()\"\n [attr.data-test-id]=\"testIds.createButton\"\n >\n {{ 'decisions.create' | translate }}\n\n <svg class=\"cds--btn__icon\" cdsIcon=\"add\" size=\"16\"></svg>\n </button>\n </ng-container>\n </ng-container>\n</valtimo-carbon-list>\n\n<valtimo-decision-deploy #decisionDeploy></valtimo-decision-deploy>\n\n<valtimo-decision-form-modal\n #decisionCreate\n (submitEvent)=\"onCreateDecision($event)\"\n></valtimo-decision-form-modal>\n\n<valtimo-decision-form-modal\n #decisionEdit\n titleKey=\"decisions.editModal.title\"\n submitKey=\"interface.save\"\n (submitEvent)=\"onEditDecision($event)\"\n></valtimo-decision-form-modal>\n\n<valtimo-confirmation-modal\n confirmButtonTextTranslationKey=\"interface.delete\"\n confirmButtonType=\"danger\"\n contentTranslationKey=\"decisions.deleteModal.content\"\n [showModalSubject$]=\"showDeleteModal$\"\n titleTranslationKey=\"decisions.deleteModal.title\"\n (confirmEvent)=\"onDeleteConfirm()\"\n></valtimo-confirmation-modal>\n", styles: ["/*!\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: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i7.AsyncPipe, name: "async" }, { kind: "ngmodule", type: RouterModule }, { kind: "ngmodule", type: CarbonListModule }, { kind: "component", type: i4$1.CarbonListComponent, selector: "valtimo-carbon-list", inputs: ["items", "fields", "tableTranslations", "paginatorConfig", "pagination", "loading", "skeletonRowCount", "actions", "actionItems", "showActionItems", "header", "hideColumnHeader", "initialSortState", "sortState", "isSearchable", "enableSingleSelection", "lastColumnTemplate", "paginationIdentifier", "showSelectionColumn", "striped", "hideToolbar", "lockedTooltipTranslationKey", "movingRowsEnabled", "dragAndDrop", "dragAndDropDisabled"], outputs: ["rowClicked", "paginationClicked", "paginationSet", "search", "sortChanged", "moveRow", "itemsReordered"] }, { kind: "ngmodule", type: IconModule }, { kind: "directive", type: i4.IconDirective, selector: "[cdsIcon], [ibmIcon]", inputs: ["ibmIcon", "cdsIcon", "size", "title", "ariaLabel", "ariaLabelledBy", "ariaHidden", "isFocusable"] }, { kind: "ngmodule", type: WidgetModule }, { kind: "component", type: DecisionDeployComponent, selector: "valtimo-decision-deploy", outputs: ["deploySuccessful"] }, { kind: "component", type: DecisionFormModalComponent, selector: "valtimo-decision-form-modal", inputs: ["titleKey", "submitKey"], outputs: ["submitEvent"] }, { kind: "ngmodule", type: ConfirmationModalModule }, { kind: "component", type: i4$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"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i4.Button, selector: "[cdsButton], [ibmButton]", inputs: ["ibmButton", "cdsButton", "size", "skeleton", "iconOnly", "isExpressive"] }] }); }
|
|
798
1363
|
}
|
|
799
1364
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: DecisionListComponent, decorators: [{
|
|
800
1365
|
type: Component,
|
|
@@ -805,12 +1370,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImpo
|
|
|
805
1370
|
IconModule,
|
|
806
1371
|
WidgetModule,
|
|
807
1372
|
DecisionDeployComponent,
|
|
1373
|
+
DecisionFormModalComponent,
|
|
1374
|
+
ConfirmationModalModule,
|
|
808
1375
|
TranslateModule,
|
|
809
1376
|
ButtonModule,
|
|
810
|
-
], 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<valtimo-carbon-list\n [items]=\"(decisionsLatestVersions$ | async) || []\"\n [loading]=\"loading$ | async\"\n [fields]=\"fields\"\n (rowClicked)=\"viewDecisionTable($event)\"\n [header]=\"false\"\n [isSearchable]=\"true\"\n>\n <ng-container carbonToolbarContent>\n <
|
|
811
|
-
}], ctorParameters: () => [{ type: DecisionService }, { type:
|
|
1377
|
+
], 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<valtimo-carbon-list\n [items]=\"(decisionsLatestVersions$ | async) || []\"\n [loading]=\"loading$ | async\"\n [fields]=\"fields\"\n [actionItems]=\"ACTION_ITEMS\"\n (rowClicked)=\"viewDecisionTable($event)\"\n [header]=\"false\"\n [isSearchable]=\"true\"\n>\n <ng-container carbonToolbarContent>\n <ng-container *ngIf=\"{canEdit: hasEditPermissions$ | async} as obs\">\n <button\n cdsButton=\"ghost\"\n iconOnly=\"true\"\n [disabled]=\"!obs.canEdit\"\n (click)=\"this.deploy.openModal()\"\n [attr.data-test-id]=\"testIds.uploadButton\"\n >\n <svg cdsIcon=\"upload\" size=\"16\"></svg>\n </button>\n\n <button\n cdsButton=\"primary\"\n [disabled]=\"!obs.canEdit\"\n (click)=\"this.create.openModal()\"\n [attr.data-test-id]=\"testIds.createButton\"\n >\n {{ 'decisions.create' | translate }}\n\n <svg class=\"cds--btn__icon\" cdsIcon=\"add\" size=\"16\"></svg>\n </button>\n </ng-container>\n </ng-container>\n</valtimo-carbon-list>\n\n<valtimo-decision-deploy #decisionDeploy></valtimo-decision-deploy>\n\n<valtimo-decision-form-modal\n #decisionCreate\n (submitEvent)=\"onCreateDecision($event)\"\n></valtimo-decision-form-modal>\n\n<valtimo-decision-form-modal\n #decisionEdit\n titleKey=\"decisions.editModal.title\"\n submitKey=\"interface.save\"\n (submitEvent)=\"onEditDecision($event)\"\n></valtimo-decision-form-modal>\n\n<valtimo-confirmation-modal\n confirmButtonTextTranslationKey=\"interface.delete\"\n confirmButtonType=\"danger\"\n contentTranslationKey=\"decisions.deleteModal.content\"\n [showModalSubject$]=\"showDeleteModal$\"\n titleTranslationKey=\"decisions.deleteModal.title\"\n (confirmEvent)=\"onDeleteConfirm()\"\n></valtimo-confirmation-modal>\n", styles: ["/*!\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"] }]
|
|
1378
|
+
}], ctorParameters: () => [{ type: DecisionService }, { type: i4.IconService }, { type: i2.Router }, { type: DecisionStateService }, { type: i2.ActivatedRoute }, { type: i0.ChangeDetectorRef }, { type: i6.EditPermissionsService }, { type: i6.GlobalNotificationService }, { type: i3.TranslateService }], propDecorators: { deploy: [{
|
|
812
1379
|
type: ViewChild,
|
|
813
1380
|
args: ['decisionDeploy']
|
|
1381
|
+
}], create: [{
|
|
1382
|
+
type: ViewChild,
|
|
1383
|
+
args: ['decisionCreate']
|
|
1384
|
+
}], edit: [{
|
|
1385
|
+
type: ViewChild,
|
|
1386
|
+
args: ['decisionEdit']
|
|
814
1387
|
}] } });
|
|
815
1388
|
|
|
816
1389
|
/*
|
|
@@ -914,6 +1487,7 @@ class DecisionModule {
|
|
|
914
1487
|
ButtonModule,
|
|
915
1488
|
IconModule,
|
|
916
1489
|
DecisionDeployComponent,
|
|
1490
|
+
DecisionFormModalComponent,
|
|
917
1491
|
DecisionModelerComponent,
|
|
918
1492
|
DecisionListComponent,
|
|
919
1493
|
DecisionDisplayComponent], exports: [DecisionModelerComponent] }); }
|
|
@@ -929,6 +1503,7 @@ class DecisionModule {
|
|
|
929
1503
|
ButtonModule,
|
|
930
1504
|
IconModule,
|
|
931
1505
|
DecisionDeployComponent,
|
|
1506
|
+
DecisionFormModalComponent,
|
|
932
1507
|
DecisionModelerComponent,
|
|
933
1508
|
DecisionListComponent,
|
|
934
1509
|
DecisionDisplayComponent] }); }
|
|
@@ -949,6 +1524,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImpo
|
|
|
949
1524
|
ButtonModule,
|
|
950
1525
|
IconModule,
|
|
951
1526
|
DecisionDeployComponent,
|
|
1527
|
+
DecisionFormModalComponent,
|
|
952
1528
|
DecisionModelerComponent,
|
|
953
1529
|
DecisionListComponent,
|
|
954
1530
|
DecisionDisplayComponent,
|
|
@@ -980,5 +1556,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImpo
|
|
|
980
1556
|
* Generated bundle index. Do not edit.
|
|
981
1557
|
*/
|
|
982
1558
|
|
|
983
|
-
export { DECISION_LIST_TEST_IDS, DECISION_MODELER_TEST_IDS, DECISION_UPLOAD_TEST_IDS, DecisionDeployComponent, DecisionDisplayComponent, DecisionListComponent, DecisionModelerComponent, DecisionModule, DecisionService, DecisionStateService, filterLatestDecisionVersions };
|
|
1559
|
+
export { DECISION_FORM_TEST_IDS, DECISION_LIST_TEST_IDS, DECISION_MODELER_TEST_IDS, DECISION_UPLOAD_TEST_IDS, DecisionDeployComponent, DecisionDisplayComponent, DecisionFormModalComponent, DecisionListComponent, DecisionModelerComponent, DecisionModule, DecisionService, DecisionStateService, createDmnXml, filterLatestDecisionVersions, parseDecisionForm, toDecisionFileName, toDecisionKey, updateDmnXml };
|
|
984
1560
|
//# sourceMappingURL=valtimo-decision.mjs.map
|