Function bodies 220 total
updateCardContent function · javascript · L337-L340 (4 LOC)web/flows.js
function updateCardContent(cardId, value) {
const card = cards.find(c => c.id === cardId);
if (card) card.content = value;
}toggleTool function · javascript · L342-L351 (10 LOC)web/flows.js
function toggleTool(cardId, toolId, enabled) {
const card = cards.find(c => c.id === cardId);
if (!card) return;
if (!card.enabledTools) card.enabledTools = [];
if (enabled && !card.enabledTools.includes(toolId)) {
card.enabledTools.push(toolId);
} else if (!enabled) {
card.enabledTools = card.enabledTools.filter(t => t !== toolId);
}
}cardsToFlowJSON function · javascript · L355-L498 (144 LOC)web/flows.js
function cardsToFlowJSON() {
// Collect all knowledge content
const knowledgeParts = [];
for (const card of cards) {
if (card.type === 'answer' && card.content) {
knowledgeParts.push(card.content);
}
}
// Check for transfer capability
const hasTransfer = cards.some(c =>
(c.type === 'actions' && (c.enabledTools || []).includes('transfer')) ||
c.type === 'transfer'
);
let kb = knowledgeParts.join('\n\n');
// Fold action instructions into KB
for (const card of cards) {
if (card.type === 'actions' && card.content) {
kb += (kb ? '\n\n' : '') + card.content;
}
if (card.type === 'transfer' && card.content) {
kb += (kb ? '\n\n' : '') + card.content;
}
}
if (hasTransfer) {
kb += (kb ? '\n\n' : '') + 'You can transfer the caller to a human agent if they request it or the issue requires human attention.';
}
const nodes = {};
lflowJSONToCards function · javascript · L502-L516 (15 LOC)web/flows.js
function flowJSONToCards(flowJson) {
if (!flowJson) {
nextCardId = 1;
return defaultCards();
}
// Version 3+: cards stored directly in metadata
if (flowJson.metadata?.version >= 3 && flowJson.metadata?.cards) {
nextCardId = flowJson.metadata.nextCardId || flowJson.metadata.cards.length + 1;
return flowJson.metadata.cards.map(c => ({ ...c }));
}
// Legacy v2: reconstruct from nodes
return legacyFlowJSONToCards(flowJson);
}legacyFlowJSONToCards function · javascript · L518-L595 (78 LOC)web/flows.js
function legacyFlowJSONToCards(flowJson) {
nextCardId = 1;
const result = [
{ id: 'card_' + nextCardId++, type: 'welcome', x: 40, y: 30, content: '' },
{ id: 'card_' + nextCardId++, type: 'answer', x: 400, y: 30, content: '' },
{ id: 'card_' + nextCardId++, type: 'actions', x: 40, y: 330, content: '', enabledTools: [] },
{ id: 'card_' + nextCardId++, type: 'close', x: 400, y: 330, content: '' },
];
if (!flowJson || !flowJson.nodes) return result;
// Restore card positions from legacy metadata
const positions = flowJson.metadata?.card_positions;
if (positions) {
const typeToCard = {};
for (const card of result) typeToCard[card.type] = card;
for (const [key, pos] of Object.entries(positions)) {
const card = typeToCard[key];
if (card && pos) {
card.x = pos.x;
card.y = pos.y;
}
}
}
const nodes = flowJson.nodes;
getNextNodes function · javascript · L597-L607 (11 LOC)web/flows.js
function getNextNodes(nodes, nodeId) {
const node = nodes[nodeId];
if (!node) return [];
const result = [];
for (const output of Object.values(node.outputs || {})) {
for (const conn of (output.connections || [])) {
if (!result.includes(conn)) result.push(conn);
}
}
return result;
}loadFlowList function · javascript · L611-L636 (26 LOC)web/flows.js
async function loadFlowList(autoLoad) {
try {
const flows = await fetchJSON('/api/flows');
const sel = document.getElementById('flowSelector');
sel.innerHTML = '<option value="">-- Select Script --</option>';
flows.forEach(f => {
const opt = document.createElement('option');
opt.value = f.id;
opt.textContent = f.name + (f.is_active ? ' (active)' : '');
sel.appendChild(opt);
});
if (autoLoad && flows.length > 0 && !currentFlowId) {
sel.value = flows[0].id;
await loadFlow(flows[0].id);
} else if (autoLoad && flows.length === 0) {
nextCardId = 1;
cards = defaultCards();
renderCards();
}
} catch (e) {
console.error('Failed to load flows:', e);
nextCardId = 1;
cards = defaultCards();
renderCards();
}
}About: code-quality intelligence by Repobility · https://repobility.com
loadFlow function · javascript · L638-L652 (15 LOC)web/flows.js
async function loadFlow(id) {
if (!id) { newFlow(); return; }
try {
const flow = await fetchJSON('/api/flows/' + id);
currentFlowId = flow.id;
document.getElementById('flowName').value = flow.name;
document.getElementById('flowActive').checked = !!flow.is_active;
document.getElementById('btnDelete').disabled = false;
cards = flowJSONToCards(flow.flow_json);
renderCards();
} catch (e) {
showToast('Failed to load flow', true);
}
}newFlow function · javascript · L654-L663 (10 LOC)web/flows.js
function newFlow() {
currentFlowId = null;
document.getElementById('flowName').value = '';
document.getElementById('flowActive').checked = false;
document.getElementById('flowSelector').value = '';
document.getElementById('btnDelete').disabled = true;
nextCardId = 1;
cards = defaultCards();
renderCards();
}saveFlow function · javascript · L665-L698 (34 LOC)web/flows.js
async function saveFlow() {
const name = document.getElementById('flowName').value.trim();
if (!name) {
showToast('Please enter a script name', true);
return;
}
const flowJson = cardsToFlowJSON();
const payload = {
name,
description: '',
flow_json: flowJson,
drawflow_json: {},
};
try {
if (currentFlowId) {
await fetchJSON('/api/flows/' + currentFlowId, 'PUT', payload);
showToast('Script saved');
} else {
const result = await fetchJSON('/api/flows', 'POST', payload);
currentFlowId = result.id;
document.getElementById('btnDelete').disabled = false;
showToast('Script created');
}
await loadFlowList();
if (currentFlowId) {
document.getElementById('flowSelector').value = currentFlowId;
}
} catch (e) {
showToast('Failed to save: ' + e.message, true);
}
}deleteFlow function · javascript · L700-L711 (12 LOC)web/flows.js
async function deleteFlow() {
if (!currentFlowId) return;
if (!confirm('Delete this script?')) return;
try {
await fetchJSON('/api/flows/' + currentFlowId, 'DELETE');
showToast('Script deleted');
newFlow();
await loadFlowList();
} catch (e) {
showToast('Failed to delete', true);
}
}toggleActive function · javascript · L713-L728 (16 LOC)web/flows.js
async function toggleActive() {
if (!currentFlowId) {
document.getElementById('flowActive').checked = false;
showToast('Save the script first', true);
return;
}
const active = document.getElementById('flowActive').checked;
const action = active ? 'activate' : 'deactivate';
try {
await fetchJSON(`/api/flows/${currentFlowId}/${action}`, 'POST');
showToast(active ? 'Script activated' : 'Script deactivated');
await loadFlowList();
} catch (e) {
showToast('Failed to toggle', true);
}
}generateFromProfile function · javascript · L732-L749 (18 LOC)web/flows.js
async function generateFromProfile() {
const btn = document.getElementById('btnGenerate');
btn.disabled = true;
btn.textContent = 'Generating...';
try {
const result = await fetchJSON('/api/flows/generate', 'POST');
currentFlowId = result.flow_id;
await loadFlow(currentFlowId);
await loadFlowList();
document.getElementById('flowSelector').value = currentFlowId;
showToast('Script generated from profile');
} catch (e) {
showToast('Generation failed: ' + e.message, true);
} finally {
btn.disabled = false;
btn.textContent = 'Generate from Profile';
}
}showTemplates function · javascript · L776-L786 (11 LOC)web/flows.js
function showTemplates() {
const modal = document.getElementById('templateModal');
const list = document.getElementById('templateList');
list.innerHTML = TEMPLATES.map((t, i) =>
`<div class="template-card" onclick="loadTemplate(${i})">
<h4>${escapeHtml(t.name)}</h4>
<p>${escapeHtml(t.description)}</p>
</div>`
).join('');
modal.classList.add('visible');
}hideTemplates function · javascript · L788-L790 (3 LOC)web/flows.js
function hideTemplates() {
document.getElementById('templateModal').classList.remove('visible');
}All rows above produced by Repobility · https://repobility.com
loadTemplate function · javascript · L792-L811 (20 LOC)web/flows.js
function loadTemplate(index) {
const tpl = TEMPLATES[index];
if (!tpl) return;
currentFlowId = null;
document.getElementById('flowName').value = tpl.name;
document.getElementById('flowActive').checked = false;
document.getElementById('flowSelector').value = '';
document.getElementById('btnDelete').disabled = true;
nextCardId = 1;
cards = tpl.cards.map(c => ({
...c,
id: 'card_' + nextCardId++,
enabledTools: c.enabledTools ? [...c.enabledTools] : undefined,
}));
renderCards();
hideTemplates();
showToast('Template loaded — edit and save');
}fetchJSON function · javascript · L815-L827 (13 LOC)web/flows.js
async function fetchJSON(url, method, body) {
const opts = { method: method || 'GET', headers: {} };
if (body) {
opts.headers['Content-Type'] = 'application/json';
opts.body = JSON.stringify(body);
}
const res = await fetch(url, opts);
if (!res.ok) {
const err = await res.json().catch(() => ({}));
throw new Error(err.error || res.statusText);
}
return res.json();
}escapeHtml function · javascript · L829-L833 (5 LOC)web/flows.js
function escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text || '';
return div.innerHTML;
}escapeAttr function · javascript · L835-L837 (3 LOC)web/flows.js
function escapeAttr(text) {
return (text || '').replace(/"/g, '"').replace(/</g, '<').replace(/>/g, '>');
}showToast function · javascript · L839-L850 (12 LOC)web/flows.js
function showToast(message, isError) {
let toast = document.querySelector('.toast');
if (!toast) {
toast = document.createElement('div');
toast.className = 'toast';
document.body.appendChild(toast);
}
toast.textContent = message;
toast.classList.toggle('error', !!isError);
toast.classList.add('visible');
setTimeout(() => toast.classList.remove('visible'), 2500);
}‹ prevpage 5 / 5