Files

771 lines
30 KiB
JavaScript

import { componentTypes } from '/core/js/common/scripts/componentTypes.js';
import { componentTemplates } from '/core/js/common/scripts/templates.js';
import { updateWorkflowConfig } from './configHandler.js';
import { attachMultiComponentListEventListeners } from './multiComponentHandler.js';
function nodeSelectDisplayComponentForm(nodeId, nodeInfo, state, existingComponent = null, componentIndex = null, containerId = 'nodeToComponentSection', multiIndex = null) {
const section = document.getElementById(containerId);
if (!section) return;
section.innerHTML = generateComponentFormHTML(nodeInfo, existingComponent);
if (existingComponent) displayComponentParams(section, existingComponent.type, existingComponent.params);
attachComponentFormEvents(section, nodeId, nodeInfo, state, existingComponent, componentIndex, multiIndex);
}
function editDisplayComponentForm(nodeId, nodeInfo, state, existingComponent, componentIndex, containerId = 'componentsList', multiIndex = null) {
const section = document.getElementById(containerId);
if (!section) return;
section.innerHTML = generateEditComponentFormHTML(nodeInfo, existingComponent);
if (existingComponent) displayComponentParams(section, existingComponent.type, existingComponent.params);
attachEditComponentFormEvents(section, nodeId, nodeInfo, state, existingComponent, componentIndex, multiIndex);
}
function generateComponentFormHTML(nodeInfo, existingComponent) {
const componentOptions = generateComponentOptions(existingComponent);
const inputPathOptions = generateInputPathOptions(nodeInfo, existingComponent);
const templateOptions = generateTemplateOptions(nodeInfo);
console.log('nodeInfo:', nodeInfo);
return `
${nodeInfo.classType ? `<h3>Node Type: ${nodeInfo.classType}</h3>` : ''}
<h4>Preset Linking</h4>
<select class="templateSelect">
<option value="">Select a template</option>
${templateOptions}
</select>
<h3>Manual Linking</h3>
<select class="inputPathSelect">
<option value="">Select an input path</option>
${inputPathOptions}
</select>
<select class="componentSelect">
<option value="">Select a component</option>
${componentOptions}
</select>
<div class="componentParams"></div>
<button class="addComponentFormButton">${existingComponent ? 'Update Component' : 'Save Component'}</button>
<button class="cancelAddComponentFormButton" style="${existingComponent ? '' : 'display: none'}">${existingComponent ? 'Cancel' : ''}</button>
`;
}
function generateEditComponentFormHTML(nodeInfo, existingComponent) {
const componentOptions = generateComponentOptions(existingComponent);
const inputPathOptions = generateInputPathOptions(nodeInfo, existingComponent);
return `
${nodeInfo.classType ? `<h3>Node Type: ${nodeInfo.classType}</h3>` : ''}
<h3>Manual Linking</h3>
<select class="inputPathSelect">
<option value="">Select an input path</option>
${inputPathOptions}
</select>
<select class="componentSelect">
<option value="">Select a component</option>
${componentOptions}
</select>
<div class="componentParams"></div>
<button class="editComponentFormButton">${existingComponent ? 'Update Component' : 'Save Component'}</button>
<button class="cancelEditComponentFormButton" style="${existingComponent ? '' : 'display: none'}">${existingComponent ? 'Cancel' : ''}</button>
`;
}
function generateTemplateOptions(nodeInfo) {
const nodeClassType = nodeInfo.classType;
const nodeInputs = nodeInfo.inputs ? Object.keys(nodeInfo.inputs) : [];
return Object.keys(componentTemplates)
.filter(templateName => {
const template = componentTemplates[templateName];
// Filter out templates not matching the nodeClassType
if (template.nodeClass && template.nodeClass !== nodeClassType) {
return false;
}
// Ensure all required inputs are present
let requiredInputs = [];
if (template.type === 'component') {
const compTemplate = template.component;
const inputName = getInputNameFromNodePath(compTemplate.params.nodePath);
requiredInputs.push(inputName);
} else if (template.type === 'components' || template.type === 'multiComponent') {
template.components.forEach(compTemplate => {
const inputName = getInputNameFromNodePath(compTemplate.params.nodePath);
requiredInputs.push(inputName);
});
}
const missingInputs = requiredInputs.filter(input => !nodeInputs.includes(input));
if (missingInputs.length > 0) {
return false;
}
return true;
})
.map(templateName => `<option value="${templateName}">${templateName}</option>`)
.join('');
}
function getInputNameFromNodePath(nodePath) {
const parts = nodePath.split('.');
return parts[parts.length - 1];
}
function generateComponentOptions(existingComponent) {
return Object.keys(componentTypes)
.filter(type => type !== 'multiComponent')
.map(type => `<option value="${type}" ${existingComponent && existingComponent.type === type ? 'selected' : ''}>${type}</option>`)
.join('');
}
function generateInputPathOptions(nodeInfo, existingComponent) {
return Object.entries(nodeInfo.inputPaths || {})
.map(([name, path]) => `<option value="${path}" ${existingComponent && existingComponent.params.nodePath === path ? 'selected' : ''}>${name}: ${path}</option>`)
.join('');
}
function attachComponentFormEvents(section, nodeId, nodeInfo, state, existingComponent, componentIndex, multiIndex = null) {
const componentSelect = section.querySelector('.componentSelect');
const templateSelect = section.querySelector('.templateSelect');
const addComponentButton = section.querySelector('.addComponentFormButton');
const cancelAddComponentButton = section.querySelector('.cancelAddComponentFormButton');
const inputPathSelect = section.querySelector('.inputPathSelect');
const componentParams = section.querySelector('.componentParams');
if (!componentSelect || !addComponentButton || !templateSelect) return;
componentSelect.addEventListener('change', () => {
const componentType = componentSelect.value;
componentType ? displayComponentParams(section, componentType, existingComponent ? existingComponent.params : {}) : clearComponentParams(section);
});
templateSelect.addEventListener('change', () => {
const templateName = templateSelect.value;
if (templateName) {
applyTemplate(nodeId, nodeInfo, state, templateName);
// clearComponentForm(section);
}
});
addComponentButton.addEventListener('click', () => {
const componentType = componentSelect.value;
if (!inputPathSelect) return;
const nodePath = inputPathSelect.value;
if (componentType && nodePath) {
console.log('existingComponent:', existingComponent);
saveComponent(section, nodeId, componentType, nodePath, state, existingComponent, componentIndex, multiIndex);
} else {
alert('Please select a component and an input path.');
}
});
cancelAddComponentButton.addEventListener('click', () => {
updateComponentsList(state);
updateWorkflowConfig(state);
});
}
function attachEditComponentFormEvents(section, nodeId, nodeInfo, state, existingComponent, componentIndex, multiIndex = null) {
const componentSelect = section.querySelector('.componentSelect');
const inputPathSelect = section.querySelector('.inputPathSelect');
const editComponentButton = section.querySelector('.editComponentFormButton');
const cancelEditComponentButton = section.querySelector('.cancelEditComponentFormButton');
const componentParams = section.querySelector('.componentParams');
if (!componentSelect || !editComponentButton) return;
componentSelect.addEventListener('change', () => {
const componentType = componentSelect.value;
componentType ? displayComponentParams(section, componentType, existingComponent ? existingComponent.params : {}) : clearComponentParams(section);
});
editComponentButton.addEventListener('click', () => {
const componentType = componentSelect.value;
const nodePath = inputPathSelect ? inputPathSelect.value : '';
if (componentType && nodePath) {
console.log('existingComponent:', existingComponent);
saveComponent(section, nodeId, componentType, nodePath, state, existingComponent, componentIndex, multiIndex);
} else {
alert('Please select a component and an input path.');
}
});
cancelEditComponentButton.addEventListener('click', () => {
updateComponentsList(state);
updateWorkflowConfig(state);
});
}
function applyTemplate(nodeId, nodeInfo, state, templateName) {
const template = componentTemplates[templateName];
if (!template) return;
if (template.type === 'component') {
const compTemplate = template.component;
const params = { ...compTemplate.params };
params.nodePath = params.nodePath.replace('{nodeId}', nodeId);
generateComponentId(compTemplate.type, state, params);
if (compTemplate.type === 'dropdown') {
enrichDropdownComponentParams(params, state, nodeId);
}
updateAssignedComponents(state, nodeId, compTemplate.type, params);
} else if (template.type === 'components') {
template.components.forEach(compTemplate => {
const params = { ...compTemplate.params };
params.nodePath = params.nodePath.replace('{nodeId}', nodeId);
generateComponentId(compTemplate.type, state, params);
if (compTemplate.type === 'dropdown') {
enrichDropdownComponentParams(params, state, nodeId);
}
updateAssignedComponents(state, nodeId, compTemplate.type, params);
});
} else if (template.type === 'multiComponent') {
const multiComponent = {
id: `multiComponent${Math.random().toString(36).substring(2, 8)}`,
label: template.label || templateName,
components: [],
};
template.components.forEach(compTemplate => {
const params = { ...compTemplate.params };
params.nodePath = params.nodePath.replace('{nodeId}', nodeId);
generateComponentId(compTemplate.type, state, params);
if (compTemplate.type === 'dropdown') {
enrichDropdownComponentParams(params, state, nodeId);
}
const componentData = {
type: compTemplate.type,
params,
inMultiComponent: true,
};
state.assignedComponents.push({ nodeId, component: componentData });
const componentIndex = state.assignedComponents.length - 1;
multiComponent.components.push({
nodeId,
component: componentData,
index: componentIndex,
});
});
state.multiComponents.push(multiComponent);
}
updateComponentsList(state);
updateWorkflowConfig(state);
}
function displayComponentParams(section, componentType, existingParams = {}) {
const paramsContainer = section.querySelector('.componentParams');
if (!paramsContainer) return;
paramsContainer.innerHTML = '<div class="parameter-group"></div>';
const paramGroup = paramsContainer.querySelector('.parameter-group');
const parameters = componentTypes[componentType] || [];
parameters.forEach(param => {
if (['nodePath', 'id', 'key', 'url'].includes(param.name)) return;
const value = existingParams[param.name] !== undefined ? existingParams[param.name] : param.value || '';
paramGroup.appendChild(createParameterInput(param, value));
});
}
function createParameterInput(param, value = '') {
const paramElement = document.createElement('div');
paramElement.className = 'parameter-item';
let inputField = '';
if (param.type === 'textarea') {
inputField = `<textarea class="parameter-input" name="${param.name}">${value}</textarea>`;
} else if (param.type === 'number') {
inputField = `<input type="number" class="parameter-input" name="${param.name}" value="${value}"${param.min !== undefined ? ` min="${param.min}"` : ''}${param.max !== undefined ? ` max="${param.max}"` : ''}${param.step !== undefined ? ` step="${param.step}"` : ''}>`;
} else if (param.type === 'select') {
inputField = generateSelectInput(param, value);
} else {
inputField = `<input type="${param.type}" class="parameter-input" name="${param.name}" value="${value}">`;
}
paramElement.innerHTML = `<label class="parameter-label" for="${param.name}">${param.label}</label>${inputField}`;
return paramElement;
}
function generateSelectInput(param, value) {
const options = (param.options || []).map(option => `<option value="${option.value}" ${option.value === value ? 'selected' : ''}>${option.label}</option>`).join('');
return `<select class="parameter-input" name="${param.name}">${options}</select>`;
}
function clearComponentParams(section) {
const paramsContainer = section.querySelector('.componentParams');
if (paramsContainer) paramsContainer.innerHTML = '';
}
function saveComponent(section, nodeId, componentType, nodePath, state, existingComponent = null, componentIndex = null, multiIndex = null) {
const params = collectComponentParams(section, componentType);
params.nodePath = nodePath;
generateComponentId(componentType, state, params);
if (componentType === 'dropdown') {
enrichDropdownComponentParams(params, state, nodeId);
}
if (multiIndex !== null && multiIndex !== undefined) {
const multiComponent = state.multiComponents[multiIndex];
if (multiComponent) {
const multiComp = multiComponent.components.find(comp => comp.index === componentIndex);
if (multiComp) {
multiComp.component = { type: componentType, params };
updateComponentsList(state);
updateWorkflowConfig(state);
clearComponentParams(section);
return;
}
}
}
updateAssignedComponents(state, nodeId, componentType, params, existingComponent, componentIndex);
updateComponentsList(state);
updateWorkflowConfig(state);
if (existingComponent !== null) {
clearComponentParams(section);
} else {
// clearComponentForm();
}
}
function collectComponentParams(section, componentType) {
const params = {};
const parameters = componentTypes[componentType] || [];
parameters.forEach(param => {
if (['nodePath', 'id'].includes(param.name)) return;
const inputElement = section.querySelector(`[name="${param.name}"]`);
if (inputElement) {
let value = inputElement.value;
if (param.type === 'number') value = value !== '' ? Number(value) : null;
params[param.name] = value;
}
});
return params;
}
function generateComponentId(componentType, state, params) {
const existingIds = getAllComponentIds(state);
let newId;
do {
newId = `${componentType}${Math.random().toString(36).substring(2, 8)}`;
} while (existingIds.includes(newId));
params.id = newId;
}
function getAllComponentIds(state) {
const ids = [];
state.assignedComponents.forEach(({ component }) => {
if (component.params && component.params.id) {
ids.push(component.params.id);
}
});
state.multiComponents.forEach(multiComponent => {
if (multiComponent.id) ids.push(multiComponent.id);
});
return ids;
}
function enrichDropdownComponentParams(params, state, nodeId) {
const nodeInfo = state.nodeToCustomNodeMap[nodeId];
const nodeName = nodeInfo.classType;
const inputName = params.nodePath.split('.').pop();
if (!params.key) params.key = inputName;
if (!params.url) params.url = nodeName;
}
function updateAssignedComponents(state, nodeId, componentType, params, existingComponent = null, componentIndex = null) {
const newComponent = { type: componentType, params };
if (existingComponent && componentIndex !== null) {
const assignedCompIndex = state.assignedComponents.findIndex(ac => ac.nodeId === nodeId && ac.component.params.id === existingComponent.params.id);
if (assignedCompIndex !== -1) {
state.assignedComponents[assignedCompIndex].component = newComponent;
}
} else {
state.assignedComponents.push({ nodeId, component: newComponent });
}
}
function updateComponentsList(state) {
const componentsListElement = document.getElementById('componentsList');
if (!componentsListElement) return;
componentsListElement.innerHTML = '<h2>Components List</h2>';
state.multiComponents.forEach((multiComponent, index) => {
const multiComponentItem = createMultiComponentListItem(multiComponent, index, state);
componentsListElement.appendChild(multiComponentItem);
});
state.assignedComponents.forEach((assignedComp, index) => {
const { nodeId, component } = assignedComp;
const nodeInfo = state.nodeToCustomNodeMap[nodeId];
const nodeType = nodeInfo ? nodeInfo.classType : 'Unknown';
if (component.inMultiComponent) return;
const componentItem = createComponentListItem(nodeId, component, index, state);
componentsListElement.appendChild(componentItem);
});
attachComponentsListEventListeners(componentsListElement, state);
attachMultiComponentListEventListeners(state);
}
function createComponentListItem(nodeId, component, index, state) {
const item = document.createElement('div');
item.className = 'component-item';
console.log('state.nodeToCustomNodeMap:', state.nodeToCustomNodeMap);
const nodeInfo = state.nodeToCustomNodeMap[nodeId];
const nodeType = nodeInfo ? nodeInfo.classType : 'Unknown';
item.innerHTML = `
<p><strong>${component.params.label || component.params.id}</strong></p>
<p>Node ID: ${nodeId} | Type: ${component.type}</p>
<p>Node Type: ${nodeType}</p>
<div class="button-group">
<button data-index="${index}" class="move-top-button" title="Move to Top">↑↑</button>
<button data-index="${index}" class="move-up-button" title="Move Up">↑</button>
<button data-index="${index}" class="move-down-button" title="Move Down">↓</button>
<button data-index="${index}" class="move-bottom-button" title="Move to Bottom">↓↓</button>
<button data-index="${index}" class="edit-component-button">Edit</button>
<button data-index="${index}" class="delete-component-button">Delete</button>
</div>
`;
return item;
}
function createMultiComponentListItem(multiComponent, index, state) {
const item = document.createElement('div');
item.className = 'component-item multi-component-item';
item.innerHTML = `
<p><strong>MultiComponent: ${multiComponent.label}</strong></p>
<p>ID: ${multiComponent.id}</p>
<div class="button-group">
<button data-multi-index="${index}" class="edit-multicomponent-button">Edit</button>
<button data-multi-index="${index}" class="delete-multicomponent-button">Delete</button>
</div>
`;
// <button data-multi-index="${index}" class="move-top-multicomponent-button" title="Move MultiComponent to Top">↑↑</button>
// <button data-multi-index="${index}" class="move-up-multicomponent-button" title="Move MultiComponent Up">↑</button>
// <button data-multi-index="${index}" class="move-down-multicomponent-button" title="Move MultiComponent Down">↓</button>
// <button data-multi-index="${index}" class="move-bottom-multicomponent-button" title="Move MultiComponent to Bottom">↓↓</button>
return item;
}
function attachComponentsListEventListeners(componentsListElement, state) {
const editButtons = componentsListElement.querySelectorAll('.edit-component-button');
const deleteButtons = componentsListElement.querySelectorAll('.delete-component-button');
const moveUpButtons = componentsListElement.querySelectorAll('.move-up-button');
const moveDownButtons = componentsListElement.querySelectorAll('.move-down-button');
const moveTopButtons = componentsListElement.querySelectorAll('.move-top-button');
const moveBottomButtons = componentsListElement.querySelectorAll('.move-bottom-button');
editButtons.forEach(button => {
button.addEventListener('click', () => {
const index = parseInt(button.getAttribute('data-index'), 10);
const assignedComp = state.assignedComponents[index];
if (!assignedComp) return;
const { nodeId, component } = assignedComp;
const nodeInfo = state.nodeToCustomNodeMap[nodeId];
// clearComponentForm();
editDisplayComponentForm(nodeId, nodeInfo, state, component, index, 'componentsList');
});
});
deleteButtons.forEach(button => {
button.addEventListener('click', () => {
const index = parseInt(button.getAttribute('data-index'), 10);
deleteComponent(index, state);
});
});
moveUpButtons.forEach(button => {
button.addEventListener('click', () => {
const index = parseInt(button.getAttribute('data-index'), 10);
moveComponentUp(index, state);
});
});
moveDownButtons.forEach(button => {
button.addEventListener('click', () => {
const index = parseInt(button.getAttribute('data-index'), 10);
moveComponentDown(index, state);
});
});
// Attach event listeners for new Move to Top and Move to Bottom buttons
moveTopButtons.forEach(button => {
button.addEventListener('click', () => {
const index = parseInt(button.getAttribute('data-index'), 10);
moveComponentToTop(index, state);
});
});
moveBottomButtons.forEach(button => {
button.addEventListener('click', () => {
const index = parseInt(button.getAttribute('data-index'), 10);
moveComponentToBottom(index, state);
});
});
const editMultiButtons = componentsListElement.querySelectorAll('.edit-multicomponent-button');
const deleteMultiButtons = componentsListElement.querySelectorAll('.delete-multicomponent-button');
const moveUpMultiButtons = componentsListElement.querySelectorAll('.move-up-multicomponent-button');
const moveDownMultiButtons = componentsListElement.querySelectorAll('.move-down-multicomponent-button');
const moveTopMultiButtons = componentsListElement.querySelectorAll('.move-top-multicomponent-button');
const moveBottomMultiButtons = componentsListElement.querySelectorAll('.move-bottom-multicomponent-button');
editMultiButtons.forEach(button => {
button.addEventListener('click', () => {
const multiIndex = parseInt(button.getAttribute('data-multi-index'), 10);
const multiComponent = state.multiComponents[multiIndex];
displayMultiComponentForm(state, multiComponent, multiIndex);
});
});
deleteMultiButtons.forEach(button => {
button.addEventListener('click', () => {
const multiIndex = parseInt(button.getAttribute('data-multi-index'), 10);
deleteMultiComponent(multiIndex, state);
});
});
moveTopMultiButtons.forEach(button => {
button.addEventListener('click', () => {
const multiIndex = parseInt(button.getAttribute('data-multi-index'), 10);
moveMultiComponentToTop(multiIndex, state);
});
});
moveBottomMultiButtons.forEach(button => {
button.addEventListener('click', () => {
const multiIndex = parseInt(button.getAttribute('data-multi-index'), 10);
moveMultiComponentToBottom(multiIndex, state);
});
});
}
function moveComponentUp(index, state) {
if (index <= 0 || index >= state.assignedComponents.length) return;
[state.assignedComponents[index - 1], state.assignedComponents[index]] =
[state.assignedComponents[index], state.assignedComponents[index - 1]];
updateComponentsList(state);
updateWorkflowConfig(state);
}
function moveComponentDown(index, state) {
if (index < 0 || index >= state.assignedComponents.length - 1) return;
[state.assignedComponents[index + 1], state.assignedComponents[index]] =
[state.assignedComponents[index], state.assignedComponents[index + 1]];
updateComponentsList(state);
updateWorkflowConfig(state);
}
function moveComponentToTop(index, state) {
if (index <= 0 || index >= state.assignedComponents.length) return;
const [component] = state.assignedComponents.splice(index, 1);
state.assignedComponents.unshift(component);
updateComponentsList(state);
updateWorkflowConfig(state);
}
function moveComponentToBottom(index, state) {
if (index < 0 || index >= state.assignedComponents.length - 1) return;
const [component] = state.assignedComponents.splice(index, 1);
state.assignedComponents.push(component);
updateComponentsList(state);
updateWorkflowConfig(state);
}
function deleteComponent(index, state) {
if (state.assignedComponents[index]) {
if (state.assignedComponents[index].component.inMultiComponent) {
state.multiComponents.forEach(multiComponent => {
multiComponent.components = multiComponent.components.filter(comp => comp.index !== index);
});
}
state.assignedComponents.splice(index, 1);
}
updateComponentsList(state);
updateWorkflowConfig(state);
}
function editDisplayMultiComponentForm(multiIndex, multiComponent, state) {
const container = document.getElementById('componentsList');
if (!container) return;
container.innerHTML = generateEditMultiComponentFormHTML(multiComponent);
if (multiComponent) displayMultiComponentParams(container, multiComponent);
attachEditMultiComponentFormEvents(container, multiIndex, multiComponent, state);
}
function generateEditMultiComponentFormHTML(multiComponent) {
return `
<h3>Edit MultiComponent: ${multiComponent.label}</h3>
<div class="multi-component-params"></div>
<button class="updateMultiComponentFormButton">Update MultiComponent</button>
<button class="cancelUpdateMultiComponentFormButton">Cancel</button>
`;
}
function displayMultiComponentParams(container, multiComponent) {
const paramsContainer = container.querySelector('.multi-component-params');
if (!paramsContainer) return;
paramsContainer.innerHTML = '<div class="multi-parameter-group"></div>';
const paramGroup = paramsContainer.querySelector('.multi-parameter-group');
paramGroup.innerHTML = `
<label for="multiLabel">Label:</label>
<input type="text" id="multiLabel" name="label" value="${multiComponent.label || ''}">
`;
}
function attachEditMultiComponentFormEvents(container, multiIndex, multiComponent, state) {
const updateButton = container.querySelector('.updateMultiComponentFormButton');
const cancelButton = container.querySelector('.cancelUpdateMultiComponentFormButton');
const paramsContainer = container.querySelector('.multi-parameter-group');
if (!updateButton || !cancelButton || !paramsContainer) return;
updateButton.addEventListener('click', () => {
const labelInput = paramsContainer.querySelector('input[name="label"]');
if (labelInput) {
multiComponent.label = labelInput.value.trim() || `MultiComponent${multiIndex + 1}`;
}
updateComponentsList(state);
updateWorkflowConfig(state);
});
cancelButton.addEventListener('click', () => {
updateComponentsList(state);
updateWorkflowConfig(state);
});
}
function moveMultiComponentUp(index, state) {
if (index <= 0 || index >= state.multiComponents.length) return;
[state.multiComponents[index - 1], state.multiComponents[index]] =
[state.multiComponents[index], state.multiComponents[index - 1]];
updateComponentsList(state);
updateWorkflowConfig(state);
}
function moveMultiComponentDown(index, state) {
if (index < 0 || index >= state.multiComponents.length - 1) return;
[state.multiComponents[index + 1], state.multiComponents[index]] =
[state.multiComponents[index], state.multiComponents[index + 1]];
updateComponentsList(state);
updateWorkflowConfig(state);
}
function moveMultiComponentToTop(index, state) {
if (index <= 0 || index >= state.multiComponents.length) return;
const [multiComponent] = state.multiComponents.splice(index, 1);
state.multiComponents.unshift(multiComponent);
updateComponentsList(state);
updateWorkflowConfig(state);
}
function moveMultiComponentToBottom(index, state) {
if (index < 0 || index >= state.multiComponents.length - 1) return;
const [multiComponent] = state.multiComponents.splice(index, 1);
state.multiComponents.push(multiComponent);
updateComponentsList(state);
updateWorkflowConfig(state);
}
function deleteMultiComponent(multiIndex, state) {
const multiComponent = state.multiComponents[multiIndex];
multiComponent.components.forEach(({ index }) => {
if (state.assignedComponents[index]) {
state.assignedComponents[index].component.inMultiComponent = false;
}
});
state.multiComponents.splice(multiIndex, 1);
updateComponentsList(state);
updateWorkflowConfig(state);
attachMultiComponentListEventListeners(state);
}
function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
export { nodeSelectDisplayComponentForm, editDisplayComponentForm, updateComponentsList };