Improve Autotask customer mapping with auto-search
Added automatic search for similar company names when opening unmapped customers in the edit modal. This speeds up the mapping process by eliminating manual searches. Changes: - Clear search box when opening customer edit modal - Auto-populate search with customer name for unmapped customers - Automatically display matching Autotask companies as suggestions - Refactor search logic into reusable performAutotaskSearch() function Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
282d34af2d
commit
9388ec4c01
@ -370,6 +370,7 @@
|
||||
if (atResults) {
|
||||
clearResults();
|
||||
}
|
||||
if (atSearchInput) atSearchInput.value = '';
|
||||
setSelectedCompanyId(null);
|
||||
setMsg("", false);
|
||||
|
||||
@ -379,66 +380,80 @@
|
||||
var atStatus = btn.getAttribute("data-autotask-mapping-status") || "";
|
||||
var atLast = btn.getAttribute("data-autotask-last-sync-at") || "";
|
||||
renderCurrentMapping(atCompanyId, atCompanyName, atStatus, atLast);
|
||||
|
||||
// Auto-search for similar companies if not yet mapped
|
||||
if (!atCompanyId && name && atSearchInput) {
|
||||
atSearchInput.value = name;
|
||||
performAutotaskSearch(name);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Reusable Autotask search function
|
||||
async function performAutotaskSearch(query) {
|
||||
if (!atResults) return;
|
||||
|
||||
var q = (query || "").trim();
|
||||
if (!q) {
|
||||
setMsg("Enter a search term.", true);
|
||||
return;
|
||||
}
|
||||
setMsg("Searching...", false);
|
||||
setSelectedCompanyId(null);
|
||||
atResults.innerHTML = "<div class=\"text-muted small\">Searching...</div>";
|
||||
|
||||
try {
|
||||
var resp = await fetch("/api/autotask/companies/search?q=" + encodeURIComponent(q), {
|
||||
method: "GET",
|
||||
credentials: "same-origin",
|
||||
});
|
||||
var data = await resp.json();
|
||||
if (!resp.ok || !data || data.status !== "ok") {
|
||||
throw new Error((data && data.message) ? data.message : "Search failed.");
|
||||
}
|
||||
var items = data.items || [];
|
||||
if (!items.length) {
|
||||
atResults.innerHTML = "<div class=\"text-muted small\">No companies found.</div>";
|
||||
setMsg("No companies found.", false);
|
||||
return;
|
||||
}
|
||||
var html = "";
|
||||
items.forEach(function (it) {
|
||||
var cid = it.id;
|
||||
var name = it.companyName || it.name || ("Company #" + cid);
|
||||
var active = (it.isActive === false) ? " (inactive)" : "";
|
||||
html +=
|
||||
"<div class=\"form-check\">" +
|
||||
"<input class=\"form-check-input\" type=\"radio\" name=\"autotaskCompanyPick\" id=\"at_company_" + cid + "\" value=\"" + cid + "\" />" +
|
||||
"<label class=\"form-check-label\" for=\"at_company_" + cid + "\">" +
|
||||
name.replace(/</g, "<").replace(/>/g, ">") +
|
||||
" <span class=\"text-muted\">(ID: " + cid + ")</span>" +
|
||||
"<span class=\"text-muted\">" + active + "</span>" +
|
||||
"</label>" +
|
||||
"</div>";
|
||||
});
|
||||
atResults.innerHTML = html;
|
||||
|
||||
var radios = atResults.querySelectorAll("input[name='autotaskCompanyPick']");
|
||||
radios.forEach(function (r) {
|
||||
r.addEventListener("change", function () {
|
||||
setSelectedCompanyId(r.value);
|
||||
setMsg("Selected company ID: " + r.value, false);
|
||||
});
|
||||
});
|
||||
|
||||
setMsg("Select a company and click Set mapping.", false);
|
||||
} catch (e) {
|
||||
atResults.innerHTML = "<div class=\"text-muted small\">No results.</div>";
|
||||
setMsg(e && e.message ? e.message : "Search failed.", true);
|
||||
}
|
||||
}
|
||||
|
||||
if (atSearchBtn && atSearchInput && atResults) {
|
||||
atSearchBtn.addEventListener("click", async function () {
|
||||
var q = (atSearchInput.value || "").trim();
|
||||
if (!q) {
|
||||
setMsg("Enter a search term.", true);
|
||||
return;
|
||||
}
|
||||
setMsg("Searching...", false);
|
||||
setSelectedCompanyId(null);
|
||||
atResults.innerHTML = "<div class=\"text-muted small\">Searching...</div>";
|
||||
|
||||
try {
|
||||
var resp = await fetch("/api/autotask/companies/search?q=" + encodeURIComponent(q), {
|
||||
method: "GET",
|
||||
credentials: "same-origin",
|
||||
});
|
||||
var data = await resp.json();
|
||||
if (!resp.ok || !data || data.status !== "ok") {
|
||||
throw new Error((data && data.message) ? data.message : "Search failed.");
|
||||
}
|
||||
var items = data.items || [];
|
||||
if (!items.length) {
|
||||
atResults.innerHTML = "<div class=\"text-muted small\">No companies found.</div>";
|
||||
setMsg("No companies found.", false);
|
||||
return;
|
||||
}
|
||||
var html = "";
|
||||
items.forEach(function (it) {
|
||||
var cid = it.id;
|
||||
var name = it.companyName || it.name || ("Company #" + cid);
|
||||
var active = (it.isActive === false) ? " (inactive)" : "";
|
||||
html +=
|
||||
"<div class=\"form-check\">" +
|
||||
"<input class=\"form-check-input\" type=\"radio\" name=\"autotaskCompanyPick\" id=\"at_company_" + cid + "\" value=\"" + cid + "\" />" +
|
||||
"<label class=\"form-check-label\" for=\"at_company_" + cid + "\">" +
|
||||
name.replace(/</g, "<").replace(/>/g, ">") +
|
||||
" <span class=\"text-muted\">(ID: " + cid + ")</span>" +
|
||||
"<span class=\"text-muted\">" + active + "</span>" +
|
||||
"</label>" +
|
||||
"</div>";
|
||||
});
|
||||
atResults.innerHTML = html;
|
||||
|
||||
var radios = atResults.querySelectorAll("input[name='autotaskCompanyPick']");
|
||||
radios.forEach(function (r) {
|
||||
r.addEventListener("change", function () {
|
||||
setSelectedCompanyId(r.value);
|
||||
setMsg("Selected company ID: " + r.value, false);
|
||||
});
|
||||
});
|
||||
|
||||
setMsg("Select a company and click Set mapping.", false);
|
||||
} catch (e) {
|
||||
atResults.innerHTML = "<div class=\"text-muted small\">No results.</div>";
|
||||
setMsg(e && e.message ? e.message : "Search failed.", true);
|
||||
}
|
||||
await performAutotaskSearch(q);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -5,6 +5,10 @@ This file documents all changes made to this project via Claude Code.
|
||||
## [2026-02-05]
|
||||
|
||||
### Added
|
||||
- Autotask customer mapping now auto-searches for similar company names when opening unmapped customers:
|
||||
- Automatically populates search box with customer name
|
||||
- Displays matching Autotask companies as suggestions
|
||||
- Speeds up mapping process by eliminating manual search for most customers
|
||||
- Autotask "Link existing ticket" now supports cross-company ticket search:
|
||||
- Added `query_tickets_by_number()` to search tickets by number across all companies
|
||||
- When searching with a ticket number (e.g., "T20260205.0001"), results include:
|
||||
@ -29,6 +33,7 @@ This file documents all changes made to this project via Claude Code.
|
||||
|
||||
### Fixed
|
||||
- Autotask "Link existing" search box now clears when opening the modal instead of retaining previous search text
|
||||
- Autotask customer mapping search box now clears when opening the edit modal instead of retaining previous search text
|
||||
- Autotask ticket resolution update now correctly preserves exact field values from GET response in PUT payload.
|
||||
The `issueType`, `subIssueType`, and `source` fields are copied with their exact values (including null)
|
||||
from the GET response, as required by Autotask API. Previously these fields were being skipped or modified.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user