Skip to content

Commit d8d4555

Browse files
feat: Add toast notifications for bulk updates, test case additions, and updates; enhance test type management with description field
1 parent 79be2f1 commit d8d4555

3 files changed

Lines changed: 82 additions & 3 deletions

File tree

support/assurance/qualityfolio/ai-generator/js/generator.js

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2834,6 +2834,7 @@
28342834
});
28352835
document.getElementById("bulkEditModal").style.display = "none";
28362836
renderResults(_cases, _ctx);
2837+
showToast(`Bulk update applied to ${ids.length} test case${ids.length === 1 ? "" : "s"}.`);
28372838
});
28382839

28392840
// Bulk run modal
@@ -2900,7 +2901,7 @@
29002901
okCount++;
29012902
});
29022903
document.getElementById("bulkRunModal").style.display = "none";
2903-
if (okCount > 0) showModal("Run Added", `Run cycle "${cycle}" added to ${okCount} case(s).`);
2904+
if (okCount > 0) showToast(`Run cycle "${cycle}" added to ${okCount} case${okCount === 1 ? "" : "s"}.`);
29042905
renderResults(_cases, _ctx);
29052906
});
29062907

@@ -3008,6 +3009,8 @@
30083009

30093010
mo.style.display = "none";
30103011
renderResults(_cases, _ctx);
3012+
const isNew = !iStr || iStr === "-1";
3013+
showToast(isNew ? "Test case added successfully." : "Test case updated successfully.");
30113014
});
30123015
["editCaseModalClose", "editCaseModalCancel"].forEach((id) =>
30133016
on(id, "click", () => {
@@ -3073,6 +3076,7 @@
30733076
};
30743077
document.getElementById("editSuiteModal").style.display = "none";
30753078
renderResults(_cases, _ctx);
3079+
showToast("Suite updated successfully.");
30763080
});
30773081
["editSuiteModalClose", "editSuiteModalCancel"].forEach((id) =>
30783082
on(id, "click", () => {
@@ -3105,6 +3109,7 @@
31053109
}
31063110
document.getElementById("editPlanModal").style.display = "none";
31073111
renderResults(_cases, _ctx);
3112+
showToast("Plan updated successfully.");
31083113
});
31093114
["editPlanModalClose", "editPlanModalCancel"].forEach((id) =>
31103115
on(id, "click", () => {
@@ -3842,6 +3847,77 @@
38423847
document.getElementById("bulkModal").style.display = "block";
38433848
}
38443849

3850+
/**
3851+
* Show a lightweight, auto-dismissing toast notification.
3852+
* @param {string} message – text to display
3853+
* @param {"success"|"error"|"info"} [type] – visual style (default: "success")
3854+
* @param {number} [duration] – ms before auto-dismiss (default: 3000)
3855+
*/
3856+
function showToast(message, type = "success", duration = 3000) {
3857+
// Inject styles once
3858+
if (!document.getElementById("qfg-toast-style")) {
3859+
const s = document.createElement("style");
3860+
s.id = "qfg-toast-style";
3861+
s.textContent = `
3862+
#qfg-toast-container {
3863+
position: fixed; bottom: 28px; right: 28px;
3864+
display: flex; flex-direction: column; gap: 10px;
3865+
z-index: 99999; pointer-events: none;
3866+
}
3867+
.qfg-toast {
3868+
display: flex; align-items: center; gap: 10px;
3869+
padding: 12px 18px; border-radius: 10px;
3870+
font-size: .85rem; font-weight: 600; line-height: 1.4;
3871+
box-shadow: 0 6px 24px rgba(0,0,0,.18);
3872+
pointer-events: auto; cursor: default;
3873+
animation: qfgToastIn .25s cubic-bezier(.4,0,.2,1) forwards;
3874+
max-width: 340px;
3875+
}
3876+
.qfg-toast.qfg-toast-out {
3877+
animation: qfgToastOut .3s cubic-bezier(.4,0,.2,1) forwards;
3878+
}
3879+
.qfg-toast-success { background:#166534; color:#dcfce7; border-left:4px solid #4ade80; }
3880+
.qfg-toast-error { background:#7f1d1d; color:#fee2e2; border-left:4px solid #f87171; }
3881+
.qfg-toast-info { background:#1e3a5f; color:#dbeafe; border-left:4px solid #60a5fa; }
3882+
.qfg-toast-icon { font-size:1.1rem; flex-shrink:0; }
3883+
.qfg-toast-close {
3884+
margin-left:auto; background:none; border:none; cursor:pointer;
3885+
color:inherit; opacity:.7; font-size:.9rem; padding:0 2px;
3886+
flex-shrink:0; line-height:1;
3887+
}
3888+
.qfg-toast-close:hover { opacity:1; }
3889+
@keyframes qfgToastIn { from{opacity:0;transform:translateY(16px)} to{opacity:1;transform:translateY(0)} }
3890+
@keyframes qfgToastOut { from{opacity:1;transform:translateY(0)} to{opacity:0;transform:translateY(16px)} }
3891+
`;
3892+
document.head.appendChild(s);
3893+
}
3894+
3895+
// Ensure container exists
3896+
let container = document.getElementById("qfg-toast-container");
3897+
if (!container) {
3898+
container = document.createElement("div");
3899+
container.id = "qfg-toast-container";
3900+
document.body.appendChild(container);
3901+
}
3902+
3903+
const icons = { success: "✅", error: "❌", info: "ℹ️" };
3904+
const toast = document.createElement("div");
3905+
toast.className = `qfg-toast qfg-toast-${type}`;
3906+
toast.innerHTML = `
3907+
<span class="qfg-toast-icon">${icons[type] || icons.success}</span>
3908+
<span>${message}</span>
3909+
<button class="qfg-toast-close" title="Dismiss">✕</button>
3910+
`;
3911+
3912+
const dismiss = () => {
3913+
toast.classList.add("qfg-toast-out");
3914+
toast.addEventListener("animationend", () => toast.remove(), { once: true });
3915+
};
3916+
toast.querySelector(".qfg-toast-close").addEventListener("click", dismiss);
3917+
container.appendChild(toast);
3918+
setTimeout(dismiss, duration);
3919+
}
3920+
38453921
function closeModal() {
38463922
document.getElementById("bulkModal").style.display = "none";
38473923
}

support/assurance/qualityfolio/ai-generator/js/settings.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,8 @@
175175
editUrl: "/pages/settings/save_test_type.sql",
176176
deleteUrl: "/pages/settings/delete_test_type.sql",
177177
fields: [
178-
{ name: "name", label: "Test Type Name", type: "text", placeholder: "e.g. Integration", required: true }
178+
{ name: "name", label: "Test Type Name", type: "text", placeholder: "e.g. Integration", required: true },
179+
{ name: "description", label: "Description", type: "text", placeholder: "e.g. Testing specific functions or features", required: false }
179180
]
180181
},
181182
scenario_types: {

support/assurance/qualityfolio/ai-generator/settings.sql

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,21 +325,23 @@ SELECT 'html' AS component, '
325325
<input class="cfg-table-search" type="text" placeholder="Search…" />
326326
</div>
327327
<table class="cfg-table" id="tt-table">
328-
<thead><tr><th>Name</th><th>Created</th><th>Actions</th></tr></thead>
328+
<thead><tr><th>Name</th><th>Description</th><th>Created</th><th>Actions</th></tr></thead>
329329
<tbody>
330330
' AS html
331331
WHERE $tab = 'test_types';
332332

333333
SELECT 'html' AS component,
334334
'<tr>
335335
<td class="cfg-name-cell">' || name || '</td>
336+
<td class="cfg-date-cell">' || COALESCE(description, '') || '</td>
336337
<td class="cfg-date-cell">' || strftime('%m-%d-%Y %H:%M:%S', created_at, 'localtime') || '</td>
337338
<td><div class="cfg-actions-cell">
338339
<button class="btn btn-sm btn-edit-action"
339340
data-action="editMember"
340341
data-entity="test_types"
341342
data-id="' || id || '"
342343
data-name="' || REPLACE(name, '"', '&quot;') || '"
344+
data-description="' || REPLACE(COALESCE(description, ''), '"', '&quot;') || '"
343345
title="Edit ' || REPLACE(name, '"', '&quot;') || '">
344346
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/></svg>
345347
</button>

0 commit comments

Comments
 (0)