diff --git a/html/webpage/assets/js/login.js b/html/webpage/assets/js/login.js
new file mode 100644
index 0000000..ec5490c
--- /dev/null
+++ b/html/webpage/assets/js/login.js
@@ -0,0 +1,54 @@
+function cleartext() {
+ $('#usernametext').val('');
+ $('#passwordtext').val('');
+}
+
+function validstring(str) {
+ if (str !== null && str.length > 0) {
+ return true;
+ }
+ return false;
+}
+
+$(document).ready(function () {
+ console.log("Login page is ready.");
+ cleartext();
+ $('#loginbtn').off('click').on('click', function () {
+ var username = $('#usernametext').val();
+ var password = $('#passwordtext').val();
+ if (!validstring(username) || !validstring(password)) {
+ alert("Please enter both username and password.");
+ cleartext();
+ return;
+ }
+ fetch('/login.html', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/x-www-form-urlencoded',
+ },
+ body: new URLSearchParams({
+ username: username,
+ password: password
+ })
+ })
+ .then(response => {
+ //console.log("Received response from server : " + response.status + " " + response.statusText+" is redirected: "+response.redirected);
+ if (response.redirected) {
+ //alert("Login successful, will redirect now.");
+ //console.log("Redirecting to: " + response.url);
+ window.location.href = response.url;
+ return;
+ }
+ if (response.status === 400 || response.status === 401) {
+ alert("Login failed");
+ cleartext();
+ }
+ })
+ .catch(error => {
+ console.error('Error:', error);
+ alert("An error occurred during login.");
+ cleartext();
+ });
+ });
+
+});
\ No newline at end of file
diff --git a/html/webpage/assets/js/messagebank.js b/html/webpage/assets/js/messagebank.js
index 5440b55..2b2a10a 100644
--- a/html/webpage/assets/js/messagebank.js
+++ b/html/webpage/assets/js/messagebank.js
@@ -44,6 +44,77 @@ function fill_messagebanktablebody(vv) {
$('#tablesize').text("Table Size: " + vv.length);
}
+/**
+ * @typedef {Object} MessageBank
+ * @property {string} Description - Description of the messagebank entry
+ * @property {string} Language - Language code
+ * @property {number} ANN_ID - ANN ID (1-100)
+ * @property {string} Voice_Type - Voice type
+ * @property {string} Message_Detail - Detailed message constructed from categories and phrases
+ * @property {string} Message_TAGS - Tags associated with the message
+ */
+
+/**
+ * Get data from modal inputs and return as MessageBank object
+ * @returns {MessageBank} messagebank object or null if validation fails
+ */
+function GetDataFromModal() {
+ let description = $messagedescription.val().trim();
+ let language = $messagelanguage.val();
+ let annid = parseInt($messageannid.val());
+ let voicetype = $messagevoicetype.val();
+ let messagedetail = "";
+ let messagetags = "";
+
+ // iterate messageselectedvariables children
+ $messageselectedvariables.children().each(function () {
+ let text = $(this).text().trim();
+ let value = $(this).val().trim();
+ console.log('selected text:' + text + ', value:' + value);
+ if (text.length > 0) {
+ k
+ if (value.length > 0) {
+ messagetags += (messagetags.length > 0 ? " " : "") + value;
+ messagedetail += (messagedetail.length > 0 ? " " : "") + text;
+ }
+
+ }
+ });
+ console.log(`Constructed Message_Detail: ${messagedetail}`);
+ console.log(`Constructed Message_TAGS: ${messagetags}`);
+
+ if (description.length === 0) {
+ alert("Description cannot be empty");
+ return null;
+ }
+ if (!language) {
+ alert("Language cannot be empty");
+ return null;
+ }
+ if (isNaN(annid) || annid < 1 || annid > 100) {
+ alert("ANN_ID must be a number between 1 and 100");
+ return null;
+ }
+ if (!voicetype) {
+ alert("Voice Type cannot be empty");
+ return null;
+ }
+ if (messagedetail.length === 0 || messagetags.length === 0) {
+ alert("Message haven't been constructed, please add categories and phrases");
+ return null;
+ }
+
+
+ let mb = {
+ Description: description,
+ Language: language,
+ ANN_ID: annid,
+ Voice_Type: voicetype,
+ Message_Detail: messagedetail,
+ Message_TAGS: messagetags
+ };
+ return mb;
+}
$(document).ready(function () {
@@ -91,22 +162,24 @@ $(document).ready(function () {
function refill_messageavailablevariables() {
$messageavailablevariables.empty();
categories.forEach(cat => {
- $messageavailablevariables.append(ListItem(`[${cat}]`));
+ if ("Phrase" === cat) return; // skip Phrase category
+ let displayCat = `[${cat}]`;
+ $messageavailablevariables.append(new Option(displayCat, displayCat));
});
let lang = $messagelanguage.val();
let vt = $messagevoicetype.val();
- if (lang && lang.length > 0){
- console.log("Selected Language:", lang);
- if (vt && vt.length > 0){
- console.log("Selected Voice Type:", vt);
-
+ if (lang && lang.length > 0) {
+ //console.log("Selected Language:", lang);
+ if (vt && vt.length > 0) {
+ //console.log("Selected Voice Type:", vt);
+
fetchAPI(`SoundBank/GetPhrases/${lang}/${vt}`, "GET", {}, null, (okdata) => {
if (Array.isArray(okdata) && okdata.length > 0) {
console.log(`Loaded ${okdata.length} phrases from soundbank for language=${lang} and voiceType=${vt}`);
- console.log(JSON.stringify(okdata));
+ //console.log(JSON.stringify(okdata));
okdata.forEach(sb => {
if (sb.description && sb.description.length > 0) {
- $messageavailablevariables.append(ListItem(`${sb.description} [${sb.TAG}]`));
+ $messageavailablevariables.append($('