<template>
<!-- we use the process form for its layout when we select and for its process creation functionality when we want a new subprocess -->
<add-process-form
:show="show"
:type="process.type"
@cancel="$emit('cancel')"
@process="emitProcess"
>
<template #title>Set Subprocess</template>
<template #title-action>
<v-switch v-model="createNewProcess" :label="'New Subprocess'"></v-switch>
</template>
<!-- Override the main area of the process form with our subprocess selection when we are in select mode -->
<template v-if="!createNewProcess" #main>
<!-- To select a process, e.g. a subprocess -->
<v-container class="pa-0">
<v-row>
<v-col class="py-0" cols="12" sm="12" md="12">
<v-autocomplete
label="Select Process"
color="primary"
v-model="selectedProcess"
:filter="filterProcesses"
:items="selectableProcesses"
item-text="name"
return-object
clearable
>
</v-autocomplete>
</v-col>
</v-row>
<v-row v-if="selectedProcess">
<v-col cols="12" sm="12" md="12">
<BpmnPreview viewerMode="navigated-viewer" :process="selectedProcess"></BpmnPreview>
</v-col>
</v-row>
</v-container>
</template>
<!-- override the buttons in the footer with custom functionality but trigger the forms functionality when we want to create a process -->
<template v-if="!createNewProcess" #actions="{ confirm, cancel, isFormValid, isSubmitting }">
<v-btn @click="cancel">Cancel</v-btn>
<v-btn :loading="isSubmitting" color="primary" @click="emitProcess(selectedProcess)"
>Set Subprocess</v-btn
>
</template>
</add-process-form>
</template>
<script>
import AddProcessForm from '../processForm/AddProcessForm.vue';
import BpmnPreview from '@/frontend/components/bpmn/BpmnPreview.vue';
import { getAllSubprocesses } from '@/frontend/helpers/process-export/export-preparation.js';
/**
* @module components
*/
/**
* @memberof module:components
* @module processes
*/
/**
* This is a dialog used to select a process to be used in a callActivity
*
* @memberof module:components.module:processes
* @module Vue:SubprocessSelection
*
* @vue-prop {Process} process - the process containing the callActivity
* @vue-prop {String} currentlySelectedId - the definitions id of the currently selected subprocess
*
* @vue-event {undefined} done - signals that we are done selecting
* @vue-event {(Object<Process>|null)} process - the process that was selected
* @vue-event {undefined} cancel - if the form should be closed without the intention of doing anything (abort)
*/
export default {
components: { AddProcessForm, BpmnPreview },
props: {
process: { type: Object, required: true },
currentlySelectedId: { type: String, required: false },
show: { type: Boolean, required: true },
},
data() {
return {
/**
* if a new process is created instead of selecting a process
* @type {boolean}
*/
createNewProcess: false,
/** The process that was newly selected */
selectedProcess: null,
/** Processes that can be selected for a callActivity */
selectableProcesses: [],
};
},
methods: {
/** filter processes based on current user input in autocomplete component */
filterProcesses(item, queryText) {
return item.name.includes(queryText);
},
/**
* Emits the selected process and the done signal
*
* @param {Object} process the selected process
*/
emitProcess(process) {
this.$emit('process', process);
this.selectedProcess = null;
this.createNewProcess = false;
this.$emit('done');
},
/**
* Remove the process and processes (indirectly) referencing it from the list of selectable processes
* (cycle protection)
**/
async filterSelectableSubprocesses() {
let processes = this.$store.getters['processStore/processes'].map(async (process) => ({
...process,
bpmn: await this.$store.getters['processStore/xmlById'](process.id),
}));
processes = await Promise.all(processes);
// hide local subprocesses to avoid problems on deployment down the line
// local processes are not deployable since they are unknown to the backend
processes = processes.filter((process) => process.shared);
let deepSubprocesses = processes.map((process) =>
getAllSubprocesses(processes, { ...process }, [process])
);
deepSubprocesses = await Promise.all(deepSubprocesses);
if (this.process) {
this.selectableProcesses = processes.filter(
(_, index) =>
!deepSubprocesses[index].some((subProcess) => subProcess.id === this.process.id)
);
}
},
async selectCurrentSubprocess() {
// don't allow user to select processes that would result in cyclic calls
await this.filterSelectableSubprocesses();
if (this.currentlySelectedId) {
// preselect the process currently used in the callActivity if in select mode
this.selectedProcess = this.selectableProcesses.find(
(process) => process.id === this.currentlySelectedId
);
}
},
},
watch: {
show: {
handler(isShown) {
if (isShown) {
this.selectCurrentSubprocess();
}
},
immediate: true,
},
},
};
</script>