diff --git a/admin/DashboardController.php b/admin/DashboardController.php index e11b413..ffccc2d 100644 --- a/admin/DashboardController.php +++ b/admin/DashboardController.php @@ -2537,47 +2537,186 @@ HTML;
🔀 Flujos
-

Acciones que se ejecutan cuando un comando o fila de menú es seleccionada.

+

Acciones que se ejecutan cuando un comando o botón de menú es seleccionado.

HTML; + // Pre-build select options for menus and endpoints + $menuOptHtml = ''; + foreach (array_keys($menus) as $mk) { + $menuOptHtml .= ''; + } + $epOptHtml = ''; + foreach ($companyEndpoints as $ep) { + $epOptHtml .= ''; + } + $flowKeys = array_keys($flows); + $flowIdx = 0; foreach ($flows as $fk => $flow) { - $ft = $flow['type'] ?? 'text'; - $fMsg = self::h($flow['message'] ?? ''); - $fFn = self::h($flow['function'] ?? 'forward_to_ai'); - $fMenu = self::h($flow['menu'] ?? ''); - echo "
-
- ID: - -
-
-
- - -
-
- - -
-
- - -
-
- - -
-
-
"; + $ft = $flow['type'] ?? 'text'; + $fMsg = self::h($flow['message'] ?? ''); + $fFn = $flow['function'] ?? 'forward_to_ai'; + $fMenu = $flow['menu'] ?? ''; + $params = $flow['params'] ?? []; + $epKey = self::h($params['endpoint_key'] ?? $flow['endpoint_key'] ?? ''); + $dMode = self::h($params['date_mode'] ?? ''); + $cap = self::h($params['caption'] ?? $flow['caption'] ?? ''); + $fname = self::h($params['filename'] ?? $flow['filename'] ?? ''); + $prompt = self::h($flow['prompt'] ?? ''); + $mGroup = self::h($flow['meta_group'] ?? ''); + $mKey = self::h($flow['meta_key'] ?? ''); + $nNode = $flow['next_node'] ?? ''; + $srcEp = self::h($flow['source_endpoint_key'] ?? ''); + $valF = self::h($flow['value_field'] ?? 'id'); + $lblF = self::h($flow['label_field'] ?? 'nombre'); + $header = self::h($flow['header'] ?? ''); + $body = self::h($flow['body'] ?? ''); + $secTit = self::h($flow['section_title'] ?? ''); + + // Build menu select with current selection + $menuSelHtml = ''; + foreach (array_keys($menus) as $mk) { + $sel = $fMenu === $mk ? ' selected' : ''; + $menuSelHtml .= ''; + } + // Build endpoint select with current selection + $epSelHtml = ''; + foreach ($companyEndpoints as $ep) { + $sel = $epKey === self::h($ep['endpoint_key']) ? ' selected' : ''; + $epSelHtml .= ''; + } + // For dynamic_list source endpoint + $dlEpSelHtml = ''; + foreach ($companyEndpoints as $ep) { + $sel = $srcEp === self::h($ep['endpoint_key']) ? ' selected' : ''; + $dlEpSelHtml .= ''; + } + // For submit_form endpoint + $sfEpSelHtml = ''; + foreach ($companyEndpoints as $ep) { + $sel = $epKey === self::h($ep['endpoint_key']) ? ' selected' : ''; + $sfEpSelHtml .= ''; + } + // Next-node select + $nnSelHtml = ''; + foreach ($flowKeys as $ofk) { + if ($ofk === $fk) continue; + $sel = $nNode === $ofk ? ' selected' : ''; + $nnSelHtml .= ''; + } + + $showText = $ft === 'text' ? '' : 'display:none'; + $showMenu = $ft === 'menu' ? '' : 'display:none'; + $showFn = $ft === 'function' ? '' : 'display:none'; + $showEp = ($ft === 'function' && $fFn === 'api_report') ? '' : 'display:none'; + $showCollect = $ft === 'collect_input' ? '' : 'display:none'; + $showDynList = $ft === 'dynamic_list' ? '' : 'display:none'; + $showSubmit = $ft === 'submit_form' ? '' : 'display:none'; + + $fnOpts = ''; + foreach (['goodbye' => '↩️ Salir (goodbye)', 'api_report' => '📄 Descargar informe', 'forward_to_ai' => '🤖 Escalar a IA', 'forward_to_agent' => '👤 Escalar a agente'] as $fv => $fl) { + $fnOpts .= ''; + } + $dmOpts = ''; + foreach (['' => 'Sin fecha', 'today' => 'Hoy', 'last_30' => 'Últimos 30 días'] as $dv => $dl) { + $dmOpts .= ''; + } + + echo " +
+
+ ID: + +
+
+
+ + +
+
+ + +
+ +
+ + +
+ + +
+ + +
+ + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+ +
+
+
"; $flowIdx++; } echo <<✕
' + - '
' + - '
' + - '
' + - '' + - '' + - '
'; - container.appendChild(div); +// Flows — mostrar/ocultar secciones según tipo seleccionado +function flowTabChange(sel) { + const card = sel.closest('.item-card'); + const v = sel.value; + const map = { + 'ftg-text': v==='text', 'ftg-menu': v==='menu', 'ftg-fn': v==='function', + 'ftg-collect': v==='collect_input', 'ftg-dynlist': v==='dynamic_list', 'ftg-submit': v==='submit_form' + }; + for (const [cls, show] of Object.entries(map)) { + const el = card.querySelector('.' + cls); + if (el) el.style.display = show ? 'flex' : 'none'; + } + if (v !== 'function') { + const ep = card.querySelector('.ftg-ep'); + if (ep) ep.style.display = 'none'; + } } -function flowTypeChange(sel) { +function flowFnTabChange(sel) { const card = sel.closest('.item-card'); - card.querySelector('.flow-text').style.display = sel.value === 'text' ? '' : 'none'; - card.querySelector('.flow-function').style.display = sel.value === 'function' ? '' : 'none'; - card.querySelector('.flow-menu').style.display = sel.value === 'menu' ? '' : 'none'; + const ep = card.querySelector('.ftg-ep'); + if (ep) ep.style.display = sel.value === 'api_report' ? 'flex' : 'none'; } function updatePreview() { diff --git a/public/index.php b/public/index.php index 2e9e46e..8cfa247 100644 --- a/public/index.php +++ b/public/index.php @@ -382,20 +382,85 @@ $routes = [ if (!empty($menus)) $config['menus'] = $menus; // Flows - $flowKeys = $_POST['flow_key'] ?? []; - $flowTypes = $_POST['flow_type'] ?? []; - $flowMessages = $_POST['flow_message'] ?? []; - $flowFunctions = $_POST['flow_function'] ?? []; - $flowMenus = $_POST['flow_menu'] ?? []; + $flowKeys = $_POST['flow_key'] ?? []; + $flowTypes = $_POST['flow_type'] ?? []; + $flowMessages = $_POST['flow_message'] ?? []; + $flowFunctions = $_POST['flow_function'] ?? []; + $flowMenus = $_POST['flow_menu'] ?? []; + $flowEpKeys = $_POST['flow_ep_key'] ?? []; + $flowDateModes = $_POST['flow_date_mode'] ?? []; + $flowFilenames = $_POST['flow_filename'] ?? []; + $flowCaptions = $_POST['flow_caption'] ?? []; + $flowPrompts = $_POST['flow_prompt'] ?? []; + $flowMetaGrps = $_POST['flow_meta_group'] ?? []; + $flowMetaKeys = $_POST['flow_meta_key'] ?? []; + $flowNextNodes = $_POST['flow_next_node'] ?? []; + $flowDlEps = $_POST['flow_dl_ep'] ?? []; + $flowValFields = $_POST['flow_val_field'] ?? []; + $flowLblFields = $_POST['flow_lbl_field'] ?? []; + $flowHeaders = $_POST['flow_header'] ?? []; + $flowBodies = $_POST['flow_body'] ?? []; + $flowSecTitles = $_POST['flow_sec_title'] ?? []; + $flowDlGroups = $_POST['flow_dl_meta_group']?? []; + $flowDlKeys = $_POST['flow_dl_meta_key'] ?? []; + $flowDlNexts = $_POST['flow_dl_next'] ?? []; + $flowSfEps = $_POST['flow_sf_ep'] ?? []; + $flowSfGroups = $_POST['flow_sf_meta_group']?? []; + $flowSfFnames = $_POST['flow_sf_filename'] ?? []; + $flowSfCaps = $_POST['flow_sf_caption'] ?? []; + $flows = []; foreach ($flowKeys as $i => $fk) { - $fk = trim($fk); - if ($fk === '') continue; + $fk = trim($fk); $ftype = $flowTypes[$i] ?? 'text'; + if ($fk === '') continue; + $f = ['type' => $ftype]; - if ($ftype === 'text') $f['message'] = trim($flowMessages[$i] ?? ''); - elseif ($ftype === 'function') $f['function'] = trim($flowFunctions[$i] ?? 'forward_to_ai'); - elseif ($ftype === 'menu') $f['menu'] = trim($flowMenus[$i] ?? ''); + + if ($ftype === 'text') { + $f['message'] = trim($flowMessages[$i] ?? ''); + + } elseif ($ftype === 'menu') { + $f['menu'] = trim($flowMenus[$i] ?? ''); + + } elseif ($ftype === 'function') { + $fn = trim($flowFunctions[$i] ?? 'forward_to_ai'); + $f['function'] = $fn; + if ($fn === 'api_report') { + $f['params'] = [ + 'endpoint_key' => trim($flowEpKeys[$i] ?? ''), + 'date_mode' => trim($flowDateModes[$i] ?? ''), + 'caption' => trim($flowCaptions[$i] ?? ''), + 'filename' => trim($flowFilenames[$i] ?? ''), + ]; + } + + } elseif ($ftype === 'collect_input') { + $nn = trim($flowNextNodes[$i] ?? ''); + $f['prompt'] = trim($flowPrompts[$i] ?? ''); + $f['meta_group'] = trim($flowMetaGrps[$i] ?? ''); + $f['meta_key'] = trim($flowMetaKeys[$i] ?? ''); + $f['next_node'] = $nn !== '' ? $nn : null; + + } elseif ($ftype === 'dynamic_list') { + $nn = trim($flowDlNexts[$i] ?? ''); + $f['source_endpoint_key'] = trim($flowDlEps[$i] ?? ''); + $f['value_field'] = trim($flowValFields[$i] ?? 'id'); + $f['label_field'] = trim($flowLblFields[$i] ?? 'nombre'); + $f['header'] = trim($flowHeaders[$i] ?? ''); + $f['body'] = trim($flowBodies[$i] ?? ''); + $f['section_title'] = trim($flowSecTitles[$i] ?? ''); + $f['meta_group'] = trim($flowDlGroups[$i] ?? ''); + $f['meta_key'] = trim($flowDlKeys[$i] ?? ''); + $f['next_node'] = $nn !== '' ? $nn : null; + + } elseif ($ftype === 'submit_form') { + $f['endpoint_key'] = trim($flowSfEps[$i] ?? ''); + $f['meta_group'] = trim($flowSfGroups[$i] ?? ''); + $f['filename'] = trim($flowSfFnames[$i] ?? ''); + $f['caption'] = trim($flowSfCaps[$i] ?? ''); + } + $flows[$fk] = $f; } if (!empty($flows)) $config['flows'] = $flows;