Search: Elasticsearch-style highlighted match snippets (results + typeahead)
CI/CD / CI · dotnet build (push) Successful in 6m9s
CI/CD / Deploy · hamkadr (push) Has been cancelled

- SearchHighlight.Snippet: extracts a ±70-char window around the first
  matching term and marks it (with ellipses) — the ES "highlight" fragment.
- Result cards (shift/job/talent) now show that snippet from the matched
  description/tags when a query is present, so you SEE where the term hit
  (e.g. «…دارای مدرک <mark>mmt</mark>…») instead of just the role.
- Typeahead suggestions gain a highlighted "sub" line (talent→tags,
  shift→city·specialty, job→facility·city) so matches show in the dropdown too.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
soroush.asadi
2026-06-08 21:43:50 +03:30
parent bd8d754ee8
commit 8b0b21f24d
7 changed files with 59 additions and 7 deletions
@@ -34,6 +34,11 @@
{
<div class="row"><span class="badge badge-distance">📍 @JalaliDate.ToPersianDigits(km.ToString("0.#")) کیلومتر از شما</span></div>
}
@{ var snip = JobsMedical.Web.Services.SearchHighlight.Snippet(Model.Description, q); }
@if (snip.Value.Length > 0)
{
<div class="search-snippet">@snip</div>
}
<div class="foot">
<span class="pay">@salary</span>
<span class="btn btn-outline" style="padding: 6px 14px;">جزئیات</span>
@@ -259,8 +259,10 @@
.then(function (items) {
if (!items || !items.length) { hide(); return; }
var html = items.map(function (it) {
var sub = it.sub ? '<span class="ns-sub">' + hi(it.sub, q) + '</span>' : '';
return '<a href="' + it.url + '"><span class="ns-type">' + esc(it.type) +
'</span><span class="ns-label">' + hi(it.label, q) + '</span></a>';
'</span><span class="ns-text"><span class="ns-label">' + hi(it.label, q) +
'</span>' + sub + '</span></a>';
}).join('');
html += '<a class="ns-all" href="/Search?Q=' + encodeURIComponent(q) + '">همه نتایج برای «' + esc(q) + '» ←</a>';
box.innerHTML = html;
@@ -35,6 +35,11 @@
}
<div class="row">📅 @JalaliDate.WeekDayName(Model.Date)، @JalaliDate.ToLongDate(Model.Date)</div>
<div class="row">🕐 @JalaliDate.Time(Model.StartTime) تا @JalaliDate.Time(Model.EndTime)</div>
@{ var snip = JobsMedical.Web.Services.SearchHighlight.Snippet(Model.Description, q); }
@if (snip.Value.Length > 0)
{
<div class="search-snippet">@snip</div>
}
<partial name="_HourBar" model="Model" />
<div class="foot">
<span class="pay">@JalaliDate.PayLabel(Model.PayType, Model.PayAmount, Model.SharePercent)</span>
@@ -40,6 +40,11 @@
}
</div>
<div class="row">📍 @Model.City?.Name@(area is not null ? "، " + area : "")</div>
@{ var snip = JobsMedical.Web.Services.SearchHighlight.Snippet(Model.Description ?? Model.Tags, q); }
@if (snip.Value.Length > 0)
{
<div class="search-snippet">@snip</div>
}
@if (tags.Count > 0)
{
<div class="tag-chips">