Merge branch 'signature-app-master' into 'master'

Signature app master

Closes #307

See merge request Chill-Projet/chill-bundles!743
This commit is contained in:
2024-11-12 20:30:00 +00:00
426 changed files with 22236 additions and 2253 deletions

View File

@@ -31,6 +31,8 @@
// Specific templates
@import './scss/notification';
@import './scss/hover.scss';
/*
* BASE LAYOUT POSITION
*/
@@ -496,6 +498,7 @@ div.workflow {
div.breadcrumb {
display: initial;
margin-bottom: 0;
margin-right: .5rem;
padding-right: 0.5em;
background-color: tint-color($chill-yellow, 90%);
border: 1px solid $chill-yellow;

View File

@@ -233,7 +233,7 @@ div.wrap-header {
}
&:last-child {}
div.wh-col {
& > div.wh-col {
&:first-child {
flex-grow: 0; flex-shrink: 1; flex-basis: auto;
}

View File

@@ -0,0 +1,11 @@
.row.row-hover {
padding: 0.3rem;
&:hover {
background-color: $gray-100;
border-top: 1px solid $gray-400;
border-bottom: 1px solid $gray-400;
}
}

View File

@@ -17,6 +17,10 @@ ul.record_actions {
display: inline-block;
}
&.slim {
margin-bottom: 0;
}
&.column {
flex-direction: column;
}

View File

@@ -1,12 +0,0 @@
const buildLinkCreate = function(workflowName, relatedEntityClass, relatedEntityId) {
let params = new URLSearchParams();
params.set('entityClass', relatedEntityClass);
params.set('entityId', relatedEntityId);
params.set('workflow', workflowName);
return `/fr/main/workflow/create?`+params.toString();
};
export {
buildLinkCreate,
};

View File

@@ -0,0 +1,22 @@
/**
* Constructs a URL for creating a workflow link associated with a specific entity.
*
* @param {string} workflowName - The name of the workflow to associate.
* @param {string} relatedEntityClass - The class/type of the related entity.
* @param {number|undefined} relatedEntityId - The unique identifier of the related entity. Must be defined.
*
* @returns {string} The constructed URL containing query parameters based on the provided arguments.
*
* @throws {Error} If the related entity ID is undefined.
*/
export const buildLinkCreate = (workflowName: string, relatedEntityClass: string, relatedEntityId: number|undefined): string => {
if (typeof (relatedEntityId) === 'undefined') {
throw new Error("the related entity id is not set");
}
let params = new URLSearchParams();
params.set('entityClass', relatedEntityClass);
params.set('entityId', relatedEntityId.toString(10));
params.set('workflow', workflowName);
return `/fr/main/workflow/create?`+params.toString();
};

View File

@@ -30,6 +30,12 @@
*/
import './collection.scss';
declare global {
interface GlobalEventHandlersEventMap {
'show-hide-show': CustomEvent<{id: number, froms: HTMLElement[], container: HTMLElement}>,
}
}
export class CollectionEventPayload {
collection: HTMLUListElement;
entry: HTMLLIElement;
@@ -107,20 +113,34 @@ export const buildRemoveButton = (collection: HTMLUListElement, entry: HTMLLIEle
return button;
}
window.addEventListener('load', () => {
const collectionsInit = new Set<string>;
const buttonsInit = new Set<string>();
const initialize = function (target: Document|Element): void {
let
addButtons: NodeListOf<HTMLButtonElement> = document.querySelectorAll("button[data-collection-add-target]"),
collections: NodeListOf<HTMLUListElement> = document.querySelectorAll("ul[data-collection-regular]");
for (let i = 0; i < addButtons.length; i++) {
let addButton = addButtons[i];
const addButton = addButtons[i];
const uniqid = addButton.dataset.uniqid as string;
if (buttonsInit.has(uniqid)) {
continue;
}
buttonsInit.add(uniqid);
addButton.addEventListener('click', (e: Event) => {
e.preventDefault();
handleAdd(e.target);
});
}
for (let i = 0; i < collections.length; i++) {
let entries: NodeListOf<HTMLLIElement> = collections[i].querySelectorAll(':scope > li');
const collection = collections[i];
const uniqid = collection.dataset.uniqid as string;
if (collectionsInit.has(uniqid)) {
continue;
}
collectionsInit.add(uniqid);
let entries: NodeListOf<HTMLLIElement> = collection.querySelectorAll(':scope > li');
for (let j = 0; j < entries.length; j++) {
if (entries[j].dataset.collectionEmptyExplain === "1") {
continue;
@@ -128,4 +148,13 @@ window.addEventListener('load', () => {
initializeRemove(collections[i], entries[j]);
}
}
};
window.addEventListener('DOMContentLoaded', () => {
initialize(document);
});
window.addEventListener('show-hide-show', (event: CustomEvent<{id: number; container: HTMLElement; froms: HTMLElement[]}>) => {
const container = event.detail.container as HTMLElement;
initialize(container);
})

View File

@@ -44,7 +44,9 @@ function loadDynamicPicker(element) {
':suggested="notPickedSuggested" ' +
':label="label" ' +
'@addNewEntity="addNewEntity" ' +
'@removeEntity="removeEntity"></pick-entity>',
'@removeEntity="removeEntity" ' +
'@addNewEntityProcessEnded="addNewEntityProcessEnded"' +
'></pick-entity>',
components: {
PickEntity,
},
@@ -97,10 +99,11 @@ function loadDynamicPicker(element) {
}
}
}
if (this.submit_on_adding_new_entity) {
input.form.submit();
}
},
addNewEntityProcessEnded() {
if (this.submit_on_adding_new_entity) {
input.form.submit();
}
},
removeEntity({entity}) {
if (-1 === this.suggested.findIndex(e => e.type === entity.type && e.id === entity.id)) {

View File

@@ -1,41 +1,145 @@
import {ShowHide} from 'ChillMainAssets/lib/show_hide/show_hide.js';
window.addEventListener('DOMContentLoaded', function() {
let
const
divTransitions = document.querySelector('#transitions'),
futureDestUsersContainer = document.querySelector('#futureDests')
futureDestUsersContainer = document.querySelector('#futureDests'),
personSignatureField = document.querySelector('#person-signature-field'),
userSignatureField = document.querySelector('#user-signature-field'),
signatureTypeChoices = document.querySelector('#signature-type-choice'),
personChoice = document.querySelector('#workflow_step_isPersonOrUserSignature_0'),
userChoice = document.querySelector('#workflow_step_isPersonOrUserSignature_1'),
signatureZone = document.querySelector('#signature-zone'),
transitionFilterContainer = document.querySelector('#transitionFilter'),
transitionsContainer = document.querySelector('#transitions'),
sendExternalContainer = document.querySelector('#sendExternalContainer')
;
if (null !== divTransitions) {
new ShowHide({
load_event: null,
froms: [divTransitions],
container: [futureDestUsersContainer],
test: function(divs, arg2, arg3) {
for (let div of divs) {
for (let input of div.querySelectorAll('input')) {
if (input.checked) {
if (input.dataset.toFinal === "1") {
return false;
} else {
return true;
}
}
}
}
// ShowHide instance for future dest users
new ShowHide({
debug: false,
load_event: null,
froms: [divTransitions],
container: [futureDestUsersContainer],
test: function(froms, event) {
for (let transition of froms) {
for (let input of transition.querySelectorAll('input')) {
if (input.checked) {
if ('1' === input.dataset.toFinal) {
return false;
}
if ('1' === input.dataset.isSentExternal) {
return false;
}
const inputData = JSON.parse(input.getAttribute('data-is-signature'))
if (inputData.includes('person') || inputData.includes('user')) {
return false;
} else {
personChoice.checked = false
userChoice.checked = false
return true;
},
});
}
}
}
}
return false;
}
});
// ShowHide instance for send external
new ShowHide({
debug: false,
load_event: null,
froms: [divTransitions],
container: [sendExternalContainer],
test: function(froms, event) {
for (let transition of froms) {
for (let input of transition.querySelectorAll('input')) {
if (input.checked) {
if ('1' === input.dataset.isSentExternal) {
return true;
}
}
}
}
return false;
}
})
// ShowHide signature zone
new ShowHide({
debug: false,
load_event: null,
froms: [divTransitions],
container: [signatureZone],
test: function(froms, event) {
for (let transition of froms) {
for (let input of transition.querySelectorAll('input')) {
if (input.checked) {
const inputData = JSON.parse(input.getAttribute('data-is-signature'))
if (inputData.includes('person') || inputData.includes('user')) {
return true;
}
}
}
}
return false;
}
});
// ShowHides for personSignatureField or userSignatureField within signature zone
new ShowHide({
debug: false,
froms: [signatureTypeChoices],
container: [personSignatureField],
test: function(froms, event) {
for (let container of froms) {
return personChoice.checked;
}
return false;
},
});
new ShowHide({
debug: false,
froms: [signatureTypeChoices],
container: [userSignatureField],
test: function(froms, event) {
for (let container of froms) {
return userChoice.checked;
}
return false;
},
});
if (null !== divTransitions) {
new ShowHide({
load_event: null,
froms: [divTransitions],
container: [futureDestUsersContainer],
test: function(divs, arg2, arg3) {
for (let div of divs) {
for (let input of div.querySelectorAll('input')) {
if (input.checked) {
if (input.dataset.toFinal === "1") {
return false;
} else {
return true;
}
}
}
}
return true;
},
});
}
let
transitionFilterContainer = document.querySelector('#transitionFilter'),
transitions = document.querySelector('#transitions')
;
if (null !== transitionFilterContainer) {
transitions.querySelectorAll('.form-check').forEach(function(row) {
transitionsContainer.querySelectorAll('.form-check').forEach(function(row) {
const isForward = row.querySelector('input').dataset.isForward;
@@ -51,6 +155,7 @@ window.addEventListener('DOMContentLoaded', function() {
}
}
}
return true;
},
toggle_callback: function (c, dir) {
for (let div of c) {
@@ -66,5 +171,4 @@ window.addEventListener('DOMContentLoaded', function() {
});
});
}
});

View File

@@ -1,164 +1,181 @@
export interface DateTime {
datetime: string;
datetime8601: string
datetime: string;
datetime8601: string;
}
export interface Civility {
id: number;
// TODO
id: number;
// TODO
}
export interface Job {
id: number;
type: "user_job";
label: {
"fr": string; // could have other key. How to do that in ts ?
}
id: number;
type: "user_job";
label: {
fr: string; // could have other key. How to do that in ts ?
};
}
export interface Center {
id: number;
type: "center";
name: string;
id: number;
type: "center";
name: string;
}
export interface Scope {
id: number;
type: "scope";
name: {
"fr": string
}
id: number;
type: "scope";
name: {
fr: string;
};
}
export interface ResultItem<T> {
result: T;
relevance: number;
}
export interface User {
type: "user";
id: number;
username: string;
text: string;
text_without_absence: string;
email: string;
user_job: Job;
label: string;
// todo: mainCenter; mainJob; etc..
type: "user";
id: number;
username: string;
text: string;
text_without_absence: string;
email: string;
user_job: Job;
label: string;
// todo: mainCenter; mainJob; etc..
}
export interface UserGroup {
type: "user_group";
id: number;
label: TranslatableString;
backgroundColor: string;
foregroundColor: string;
excludeKey: string;
text: string;
}
export type UserGroupOrUser = User | UserGroup;
export interface UserAssociatedInterface {
type: "user";
id: number;
};
export type TranslatableString = {
fr?: string;
nl?: string;
type: "user";
id: number;
}
export type TranslatableString = {
fr?: string;
nl?: string;
};
export interface Postcode {
id: number;
name: string;
code: string;
center: Point;
id: number;
name: string;
code: string;
center: Point;
}
export type Point = {
type: "Point";
coordinates: [lat: number, lon: number];
}
type: "Point";
coordinates: [lat: number, lon: number];
};
export interface Country {
id: number;
name: TranslatableString;
code: string;
id: number;
name: TranslatableString;
code: string;
}
export type AddressRefStatus = 'match'|'to_review'|'reviewed';
export type AddressRefStatus = "match" | "to_review" | "reviewed";
export interface Address {
type: "address";
address_id: number;
text: string;
street: string;
streetNumber: string;
postcode: Postcode;
country: Country;
floor: string | null;
corridor: string | null;
steps: string | null;
flat: string | null;
buildingName: string | null;
distribution: string | null;
extra: string | null;
confidential: boolean;
lines: string[];
addressReference: AddressReference | null;
validFrom: DateTime;
validTo: DateTime | null;
point: Point | null;
refStatus: AddressRefStatus;
isNoAddress: boolean;
type: "address";
address_id: number;
text: string;
street: string;
streetNumber: string;
postcode: Postcode;
country: Country;
floor: string | null;
corridor: string | null;
steps: string | null;
flat: string | null;
buildingName: string | null;
distribution: string | null;
extra: string | null;
confidential: boolean;
lines: string[];
addressReference: AddressReference | null;
validFrom: DateTime;
validTo: DateTime | null;
point: Point | null;
refStatus: AddressRefStatus;
isNoAddress: boolean;
}
export interface AddressWithPoint extends Address {
point: Point
point: Point;
}
export interface AddressReference {
id: number;
createdAt: DateTime | null;
deletedAt: DateTime | null;
municipalityCode: string;
point: Point;
postcode: Postcode;
refId: string;
source: string;
street: string;
streetNumber: string;
updatedAt: DateTime | null;
id: number;
createdAt: DateTime | null;
deletedAt: DateTime | null;
municipalityCode: string;
point: Point;
postcode: Postcode;
refId: string;
source: string;
street: string;
streetNumber: string;
updatedAt: DateTime | null;
}
export interface SimpleGeographicalUnit {
id: number;
layerId: number;
unitName: string;
unitRefId: string;
id: number;
layerId: number;
unitName: string;
unitRefId: string;
}
export interface GeographicalUnitLayer {
id: number;
name: TranslatableString;
refId: string;
id: number;
name: TranslatableString;
refId: string;
}
export interface Location {
type: "location";
id: number;
active: boolean;
address: Address | null;
availableForUsers: boolean;
createdAt: DateTime | null;
createdBy: User | null;
updatedAt: DateTime | null;
updatedBy: User | null;
email: string | null
name: string;
phonenumber1: string | null;
phonenumber2: string | null;
locationType: LocationType;
type: "location";
id: number;
active: boolean;
address: Address | null;
availableForUsers: boolean;
createdAt: DateTime | null;
createdBy: User | null;
updatedAt: DateTime | null;
updatedBy: User | null;
email: string | null;
name: string;
phonenumber1: string | null;
phonenumber2: string | null;
locationType: LocationType;
}
export interface LocationAssociated {
type: "location";
id: number;
type: "location";
id: number;
}
export interface LocationType {
type: "location-type";
id: number;
active: boolean;
addressRequired: "optional" | "required";
availableForUsers: boolean;
editableByUsers: boolean;
contactData: "optional" | "required";
title: TranslatableString;
type: "location-type";
id: number;
active: boolean;
addressRequired: "optional" | "required";
availableForUsers: boolean;
editableByUsers: boolean;
contactData: "optional" | "required";
title: TranslatableString;
}
export interface NewsItemType {
@@ -168,3 +185,8 @@ export interface NewsItemType {
startDate: DateTime;
endDate: DateTime | null;
}
export interface WorkflowAvailable {
name: string;
text: string;
}

View File

@@ -9,13 +9,16 @@
</template>
<template v-slot:tbody>
<tr v-for="(w, i) in workflows.results" :key="`workflow-${i}`">
<td>{{ w.title }}</td>
<td>
{{ w.title }}
</td>
<td>
<div class="workflow">
<div class="breadcrumb">
<i class="fa fa-circle me-1 text-chill-yellow mx-2"></i>
<span class="mx-2">{{ getStep(w) }}</span>
</div>
<span v-if="w.isOnHoldAtCurrentStep" class="badge bg-success rounded-pill">{{ $t('on_hold') }}</span>
</div>
</td>
<td v-if="w.datas.persons !== null">

View File

@@ -41,6 +41,7 @@ const appMessages = {
Step: "Étape",
concerned_users: "Usagers concernés",
Object_workflow: "Objet du workflow",
on_hold: "En attente",
show_entity: "Voir {entity}",
the_activity: "l'échange",
the_course: "le parcours",

View File

@@ -62,7 +62,7 @@ export default {
required: false,
}
},
emits: ['addNewEntity', 'removeEntity'],
emits: ['addNewEntity', 'removeEntity', 'addNewEntityProcessEnded'],
components: {
AddPersons,
},
@@ -121,6 +121,7 @@ export default {
);
this.$refs.addPersons.resetSearch(); // to cast child method
modal.showModal = false;
this.$emit('addNewEntityProcessEnded');
},
removeEntity(entity) {
if (!this.$props.removableIfSet) {

View File

@@ -0,0 +1,26 @@
<script setup lang="ts">
import {UserGroup} from "../../../types";
import {computed} from "vue";
interface UserGroupRenderBoxProps {
userGroup: UserGroup;
}
const props = defineProps<UserGroupRenderBoxProps>();
const styles = computed<{color: string, "background-color": string}>(() => {
return {
color: props.userGroup.foregroundColor,
"background-color": props.userGroup.backgroundColor,
}
});
</script>
<template>
<span class="badge-user-group" :style="styles">{{ userGroup.label.fr }}</span>
</template>
<style scoped lang="scss">
</style>

View File

@@ -6,7 +6,7 @@
<div>
<div class="item-row col">
<h2>{{ w.title }}</h2>
<div class="flex-grow-1 ms-3 h3">
<div class="flex-grow-1 ms-3 h3">
<div class="visually-hidden">
{{ w.relatedEntityClass }}
{{ w.relatedEntityId }}
@@ -38,6 +38,7 @@
</span>
</template>
</div>
<span v-if="w.isOnHoldAtCurrentStep" class="badge bg-success rounded-pill">{{ $t('on_hold') }}</span>
</div>
<div class="item-row">
@@ -73,7 +74,8 @@ const i18n = {
you_subscribed_to_all_steps: "Vous recevrez une notification à chaque étape",
you_subscribed_to_final_step: "Vous recevrez une notification à l'étape finale",
by: "Par",
at: "Le"
at: "Le",
on_hold: "En attente"
}
}
}
@@ -100,11 +102,17 @@ export default {
},
getPopContent(step) {
if (step.transitionPrevious != null) {
return `<ul class="small_in_title">
<li><span class="item-key">${i18n.messages.fr.by} : </span><b>${step.transitionPreviousBy.text}</b></li>
<li><span class="item-key">${i18n.messages.fr.at} : </span><b>${this.formatDate(step.transitionPreviousAt.datetime)}</b></li>
</ul>`
;
if (step.transitionPreviousBy !== null) {
return `<ul class="small_in_title">
<li><span class="item-key">${i18n.messages.fr.by} : </span><b>${step.transitionPreviousBy.text}</b></li>
<li><span class="item-key">${i18n.messages.fr.at} : </span><b>${this.formatDate(step.transitionPreviousAt.datetime)}</b></li>
</ul>`
;
} else {
return `<ul class="small_in_title">
<li><span class="item-key">${i18n.messages.fr.at} : </span><b>${this.formatDate(step.transitionPreviousAt.datetime)}</b></li>
</ul>`
}
}
},
formatDate(datetime) {

View File

@@ -1,20 +1,13 @@
<template>
<button v-if="hasWorkflow"
class="btn btn-primary"
@click="openModal">
<b>{{ countWorkflows }}</b>
<template v-if="countWorkflows > 1">{{ $t('workflows') }}</template>
<template v-else>{{ $t('workflow') }}</template>
</button>
<pick-workflow v-else-if="allowCreate"
<pick-workflow
:relatedEntityClass="this.relatedEntityClass"
:relatedEntityId="this.relatedEntityId"
:workflowsAvailables="workflowsAvailables"
:preventDefaultMoveToGenerate="this.$props.preventDefaultMoveToGenerate"
:goToGenerateWorkflowPayload="this.goToGenerateWorkflowPayload"
:countExistingWorkflows="countWorkflows"
@go-to-generate-workflow="goToGenerateWorkflow"
@click-open-list="openModal"
></pick-workflow>
<teleport to="body">
@@ -39,6 +32,8 @@
:workflowsAvailables="workflowsAvailables"
:preventDefaultMoveToGenerate="this.$props.preventDefaultMoveToGenerate"
:goToGenerateWorkflowPayload="this.goToGenerateWorkflowPayload"
:countExistingWorkflows="countWorkflows"
:embedded-within-list-modal="true"
@go-to-generate-workflow="this.goToGenerateWorkflow"
></pick-workflow>
</template>

View File

@@ -1,63 +1,104 @@
<template>
<template v-if="workflowsAvailables.length >= 1">
<div class="dropdown d-grid gap-2">
<template v-if="props.workflowsAvailables.length >= 1">
<div v-if="countExistingWorkflows == 0 || embeddedWithinListModal" class="dropdown d-grid gap-2">
<button class="btn btn-primary dropdown-toggle" type="button" id="createWorkflowButton" data-bs-toggle="dropdown" aria-expanded="false">
Créer un workflow
</button>
<ul class="dropdown-menu" aria-labelledby="createWorkflowButton">
<li v-for="w in workflowsAvailables" :key="w.name">
<a class="dropdown-item" :href="makeLink(w.name)" @click.prevent="goToGenerateWorkflow($event, w.name)">{{ w.text }}</a>
<li v-for="w in props.workflowsAvailables" :key="w.name">
<button class="dropdown-item" type="button" @click.prevent="goToGenerateWorkflow($event, w.name)">{{ w.text }}</button>
</li>
</ul>
</div>
<div v-else>
<div class="btn-group">
<button @click="emit('clickOpenList')" class="btn btn-primary">
<template v-if="countExistingWorkflows === 1">
1 workflow associé
</template>
<template v-else>
{{ countExistingWorkflows }} workflows associés
</template>
</button>
<button class="btn btn-primary dropdown-toggle dropdown-toggle-split" type="button" id="createWorkflowButton" data-bs-toggle="dropdown" aria-expanded="false">
<span class="visually-hidden">Liste des workflows disponibles</span>
</button>
<ul class="dropdown-menu" aria-labelledby="createWorkflowButton">
<li v-for="w in props.workflowsAvailables" :key="w.name">
<button class="dropdown-item" type="button" @click.prevent="goToGenerateWorkflow($event, w.name)">{{ w.text }}</button>
</li>
</ul>
</div>
</div>
</template>
<template v-else>
<div v-if="countExistingWorkflows > 0" class="dropdown d-grid gap-2">
<button @click="emit('clickOpenList')" class="btn btn-primary" type="button" id="createWorkflowButton" data-bs-toggle="dropdown" aria-expanded="false">
<template v-if="countExistingWorkflows === 1">
1 workflow associé
</template>
<template v-else>
{{ countExistingWorkflows }} workflows associés
</template>
</button>
</div>
</template>
</template>
<script>
<script setup lang="ts">
import {buildLinkCreate} from 'ChillMainAssets/lib/entity-workflow/api.js';
import {buildLinkCreate} from '../../../lib/entity-workflow/api';
import {WorkflowAvailable} from "../../../types";
export default {
name: "PickWorkflow",
props: {
relatedEntityClass: {
type: String,
required: true,
},
relatedEntityId: {
type: Number,
required: false,
},
workflowsAvailables: {
type: Array,
required: true,
},
preventDefaultMoveToGenerate: {
type: Boolean,
required: false,
default: false,
},
goToGenerateWorkflowPayload: {
required: false,
default: {}
},
},
emits: ['goToGenerateWorkflow'],
methods: {
makeLink(workflowName) {
return buildLinkCreate(workflowName, this.relatedEntityClass, this.relatedEntityId);
},
goToGenerateWorkflow(event, workflowName) {
console.log('goToGenerateWorkflow', event, workflowName);
interface PickWorkflowConfig {
relatedEntityClass: string;
/**
* Represents the identifier of a related entity.
* This variable can store either a numerical value representing the entity's ID or an undefined value
* if the related entity is not specified or available, for instance when the entity is created within
* the interface and the id will be available later
*/
relatedEntityId: number|undefined;
workflowsAvailables: WorkflowAvailable[];
preventDefaultMoveToGenerate: boolean;
goToGenerateWorkflowPayload: object;
countExistingWorkflows: number;
/**
* if true, this button will not present a splitted button
*/
embeddedWithinListModal: boolean;
}
if (!this.$props.preventDefaultMoveToGenerate) {
console.log('to go generate');
window.location.assign(this.makeLink(workflowName));
}
const props = withDefaults(defineProps<PickWorkflowConfig>(), {preventDefaultMoveToGenerate: false, goToGenerateWorkflowPayload: {}, allowCreateWorkflow: false});
this.$emit('goToGenerateWorkflow', {event, workflowName, link: this.makeLink(workflowName), payload: this.goToGenerateWorkflowPayload});
}
const emit = defineEmits<{
(e: 'goToGenerateWorkflow', {event: MouseEvent, workflowName: string, isLinkValid: boolean, link: string, payload: object}): void;
(e: 'clickOpenList'): void;
}>();
const makeLink = (workflowName: string): string => buildLinkCreate(workflowName, props.relatedEntityClass, props.relatedEntityId);
const goToGenerateWorkflow = (event: MouseEvent, workflowName: string): void => {
console.log('goToGenerateWorkflow', event, workflowName);
let link = '';
let isLinkValid = false;
try {
link = makeLink(workflowName);
isLinkValid = true;
} catch (e) {
console.info("could not generate link to create workflow, maybe the relatedEntityId is not yet known", e);
}
if (!props.preventDefaultMoveToGenerate) {
window.location.assign(link);
}
emit('goToGenerateWorkflow', {event, workflowName, link, isLinkValid, payload: props.goToGenerateWorkflowPayload});
}
const goToDuplicateRelatedEntity = (event: MouseEvent, workflowName: string): void => {
}
</script>