Spaces:
Building
Building
Update static/js/project.js
Browse files- static/js/project.js +95 -159
static/js/project.js
CHANGED
@@ -1,183 +1,119 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
select.appendChild(option);
|
13 |
-
});
|
14 |
-
})
|
15 |
-
.catch(err => console.error(err));
|
16 |
}
|
17 |
|
18 |
function loadProjectDetails() {
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
apiGet(`/project/${project}/latest`)
|
23 |
.then(data => {
|
24 |
-
|
25 |
-
const info = document.getElementById('project-info');
|
26 |
-
details.classList.remove('d-none');
|
27 |
-
|
28 |
-
let html = `<p><strong>Version:</strong> ${data.version_number}</p>`;
|
29 |
-
html += `<p><strong>Published:</strong> ${data.published ? 'β
Yes' : 'β No'}</p>`;
|
30 |
-
html += `<div><strong>Intents:</strong><ul>`;
|
31 |
-
if (Array.isArray(data.intents) && data.intents.length > 0) {
|
32 |
-
data.intents.forEach(intent => {
|
33 |
-
html += `<li>${intent.name}
|
34 |
-
<button class="btn btn-sm btn-primary ml-2" onclick="editIntent('${intent.name}')">Edit</button>
|
35 |
-
<button class="btn btn-sm btn-danger ml-2" onclick="removeIntent('${intent.name}')">β</button>
|
36 |
-
</li>`;
|
37 |
-
});
|
38 |
-
} else {
|
39 |
-
html += `<li>No intents defined.</li>`;
|
40 |
-
}
|
41 |
-
html += `</ul><button class="btn btn-sm btn-success" onclick="addIntent()">+ Add Intent</button></div>`;
|
42 |
-
info.innerHTML = html;
|
43 |
-
|
44 |
-
if (data.published) {
|
45 |
-
document.querySelectorAll('#project-info input, #project-info button').forEach(el => {
|
46 |
-
el.disabled = true;
|
47 |
-
});
|
48 |
-
}
|
49 |
})
|
50 |
-
.catch(
|
51 |
-
|
52 |
-
|
53 |
-
function addIntent() {
|
54 |
-
const project = document.getElementById('project-select').value;
|
55 |
-
const intentName = prompt('Enter new intent name:');
|
56 |
-
if (!intentName) return;
|
57 |
-
|
58 |
-
apiPost('/project/add_intent', { project_name: project, intent_name: intentName })
|
59 |
-
.then(data => {
|
60 |
-
showResult('project-result', data);
|
61 |
-
loadProjectDetails();
|
62 |
-
})
|
63 |
-
.catch(err => {
|
64 |
-
console.error(err);
|
65 |
-
alert('Failed to add intent.');
|
66 |
});
|
67 |
}
|
68 |
|
69 |
-
function
|
70 |
-
const
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
.
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
}
|
83 |
-
|
84 |
-
function editIntent(name) {
|
85 |
-
const project = document.getElementById('project-select').value;
|
86 |
-
|
87 |
-
apiGet(`/project/${project}/latest`)
|
88 |
-
.then(data => {
|
89 |
-
const intent = data.intents.find(i => i.name === name);
|
90 |
-
if (!intent) {
|
91 |
-
alert('Intent not found.');
|
92 |
-
return;
|
93 |
-
}
|
94 |
-
|
95 |
-
document.getElementById('intent-project-name').value = project;
|
96 |
-
document.getElementById('intent-name').value = intent.name;
|
97 |
-
document.getElementById('intent-action').value = intent.action || '';
|
98 |
-
document.getElementById('intent-fallback').value = intent.fallback_error_message || '';
|
99 |
-
document.getElementById('intent-prompt').value = intent.humanization_prompt || '';
|
100 |
-
document.getElementById('intent-examples').value = (intent.examples || []).join(', ');
|
101 |
-
currentParameters = intent.parameters || [];
|
102 |
-
populateParameterTable(currentParameters);
|
103 |
-
|
104 |
-
$('#intentModal').modal('show');
|
105 |
-
})
|
106 |
-
.catch(err => console.error(err));
|
107 |
-
}
|
108 |
-
|
109 |
-
function saveIntent() {
|
110 |
-
const project = document.getElementById('intent-project-name').value;
|
111 |
-
const name = document.getElementById('intent-name').value;
|
112 |
-
const action = document.getElementById('intent-action').value;
|
113 |
-
const fallback = document.getElementById('intent-fallback').value;
|
114 |
-
const prompt = document.getElementById('intent-prompt').value;
|
115 |
-
const examples = document.getElementById('intent-examples').value.split(',').map(e => e.trim());
|
116 |
-
|
117 |
-
const intentData = {
|
118 |
-
action: action,
|
119 |
-
fallback_error_message: fallback,
|
120 |
-
humanization_prompt: prompt,
|
121 |
-
examples: examples,
|
122 |
-
parameters: currentParameters
|
123 |
-
};
|
124 |
-
|
125 |
-
apiPost('/project/update_intent', {
|
126 |
-
project_name: project,
|
127 |
-
intent_name: name,
|
128 |
-
intent_data: intentData
|
129 |
-
})
|
130 |
-
.then(data => {
|
131 |
-
showResult('project-result', data);
|
132 |
-
$('#intentModal').modal('hide');
|
133 |
-
loadProjectDetails();
|
134 |
-
})
|
135 |
-
.catch(err => {
|
136 |
-
console.error(err);
|
137 |
-
alert('Failed to save intent.');
|
138 |
});
|
|
|
|
|
|
|
139 |
}
|
140 |
|
141 |
function saveProject() {
|
142 |
-
|
|
|
|
|
|
|
143 |
}
|
144 |
|
145 |
function publishProject() {
|
146 |
-
|
|
|
|
|
|
|
147 |
}
|
148 |
|
149 |
-
function
|
150 |
-
|
151 |
-
|
152 |
-
parameters.forEach((param, index) => {
|
153 |
-
const row = document.createElement('tr');
|
154 |
-
row.innerHTML = `
|
155 |
-
<td><input type="text" class="form-control" value="${param.name || ''}" onchange="updateParam(${index}, 'name', this.value)"></td>
|
156 |
-
<td>
|
157 |
-
<select class="form-control" onchange="updateParam(${index}, 'type', this.value)">
|
158 |
-
<option value="string" ${param.type === 'string' ? 'selected' : ''}>string</option>
|
159 |
-
<option value="int" ${param.type === 'int' ? 'selected' : ''}>int</option>
|
160 |
-
<option value="float" ${param.type === 'float' ? 'selected' : ''}>float</option>
|
161 |
-
</select>
|
162 |
-
</td>
|
163 |
-
<td><input type="text" class="form-control" value="${param.regex || ''}" onchange="updateParam(${index}, 'regex', this.value)"></td>
|
164 |
-
<td><input type="text" class="form-control" value="${param.validation_message || ''}" onchange="updateParam(${index}, 'validation_message', this.value)"></td>
|
165 |
-
<td><button class="btn btn-sm btn-danger" onclick="removeParameterRow(${index})">Delete</button></td>
|
166 |
-
`;
|
167 |
-
body.appendChild(row);
|
168 |
-
});
|
169 |
}
|
170 |
|
171 |
-
function
|
172 |
-
|
173 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
174 |
}
|
175 |
|
176 |
-
function
|
177 |
-
|
178 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
179 |
}
|
180 |
|
181 |
-
function
|
182 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
183 |
}
|
|
|
1 |
+
// project.js
|
2 |
+
document.addEventListener('DOMContentLoaded', function() {
|
3 |
+
loadProjectDetails();
|
4 |
+
setupEventListeners();
|
5 |
+
});
|
6 |
+
|
7 |
+
function setupEventListeners() {
|
8 |
+
document.getElementById('saveChangesBtn').addEventListener('click', saveProject);
|
9 |
+
document.getElementById('publishVersionBtn').addEventListener('click', publishProject);
|
10 |
+
document.getElementById('addIntentBtn').addEventListener('click', showAddIntentModal);
|
11 |
+
document.getElementById('newVersionBtn').addEventListener('click', showNewVersionModal);
|
|
|
|
|
|
|
|
|
12 |
}
|
13 |
|
14 |
function loadProjectDetails() {
|
15 |
+
fetch('/project/details')
|
16 |
+
.then(response => response.json())
|
|
|
|
|
17 |
.then(data => {
|
18 |
+
renderProjectDetails(data);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
})
|
20 |
+
.catch(error => {
|
21 |
+
console.error('Error loading project details:', error);
|
22 |
+
alert('Failed to load project details.');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
23 |
});
|
24 |
}
|
25 |
|
26 |
+
function renderProjectDetails(data) {
|
27 |
+
const container = document.getElementById('projectDetails');
|
28 |
+
container.innerHTML = '';
|
29 |
+
|
30 |
+
const published = data.published ? 'β
Yes' : 'β No';
|
31 |
+
container.innerHTML += `<p><strong>Version:</strong> ${data.version}</p>`;
|
32 |
+
container.innerHTML += `<p><strong>Published:</strong> ${published}</p>`;
|
33 |
+
const list = document.createElement('ul');
|
34 |
+
data.intents.forEach(intent => {
|
35 |
+
const li = document.createElement('li');
|
36 |
+
li.style.marginBottom = '8px';
|
37 |
+
li.innerHTML = `${intent.name}
|
38 |
+
<button class="btn btn-sm btn-primary" onclick="editIntent('${intent.id}')">Edit</button>
|
39 |
+
<button class="btn btn-sm btn-danger" onclick="removeIntent('${intent.id}')">-</button>`;
|
40 |
+
list.appendChild(li);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
});
|
42 |
+
container.appendChild(list);
|
43 |
+
|
44 |
+
document.getElementById('publishVersionBtn').disabled = data.published;
|
45 |
}
|
46 |
|
47 |
function saveProject() {
|
48 |
+
fetch('/project/update', { method: 'POST' })
|
49 |
+
.then(response => response.json())
|
50 |
+
.then(data => alert('Project saved!'))
|
51 |
+
.catch(error => alert('Failed to save project.'));
|
52 |
}
|
53 |
|
54 |
function publishProject() {
|
55 |
+
fetch('/project/publish', { method: 'POST' })
|
56 |
+
.then(response => response.json())
|
57 |
+
.then(data => alert('Project published!'))
|
58 |
+
.catch(error => alert('Failed to publish project.'));
|
59 |
}
|
60 |
|
61 |
+
function showAddIntentModal() {
|
62 |
+
// show modal for adding intent and API info
|
63 |
+
$('#addIntentModal').modal('show');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
64 |
}
|
65 |
|
66 |
+
function showNewVersionModal() {
|
67 |
+
fetch('/project/versions')
|
68 |
+
.then(response => response.json())
|
69 |
+
.then(versions => {
|
70 |
+
const select = document.getElementById('baseVersionSelect');
|
71 |
+
select.innerHTML = '';
|
72 |
+
versions.forEach(v => {
|
73 |
+
const option = document.createElement('option');
|
74 |
+
option.value = v.id;
|
75 |
+
option.textContent = `Version ${v.number}`;
|
76 |
+
select.appendChild(option);
|
77 |
+
});
|
78 |
+
$('#newVersionModal').modal('show');
|
79 |
+
})
|
80 |
+
.catch(error => {
|
81 |
+
alert('Failed to load versions.');
|
82 |
+
});
|
83 |
}
|
84 |
|
85 |
+
function createNewVersion() {
|
86 |
+
const baseVersionId = document.getElementById('baseVersionSelect').value;
|
87 |
+
fetch('/project/new-version', {
|
88 |
+
method: 'POST',
|
89 |
+
headers: { 'Content-Type': 'application/json' },
|
90 |
+
body: JSON.stringify({ base_version_id: baseVersionId })
|
91 |
+
})
|
92 |
+
.then(response => response.json())
|
93 |
+
.then(data => {
|
94 |
+
alert('New version created!');
|
95 |
+
loadProjectDetails();
|
96 |
+
})
|
97 |
+
.catch(error => alert('Failed to create new version.'));
|
98 |
}
|
99 |
|
100 |
+
function loadSparkProjects() {
|
101 |
+
fetch('/spark/projects')
|
102 |
+
.then(response => response.json())
|
103 |
+
.then(data => {
|
104 |
+
if (data.error) {
|
105 |
+
alert('β Spark service unreachable.');
|
106 |
+
return;
|
107 |
+
}
|
108 |
+
const list = document.getElementById('sparkProjectList');
|
109 |
+
list.innerHTML = '';
|
110 |
+
data.projects.forEach(p => {
|
111 |
+
const li = document.createElement('li');
|
112 |
+
li.textContent = p.name;
|
113 |
+
list.appendChild(li);
|
114 |
+
});
|
115 |
+
})
|
116 |
+
.catch(error => {
|
117 |
+
alert('β Spark service unreachable.');
|
118 |
+
});
|
119 |
}
|