MediaWiki:Common.js: Difference between revisions
OCR review UX: person cards, apply preview, Advanced |
OCR: person cards clarify scan vs wiki page vs team update |
||
| Line 1,358: | Line 1,358: | ||
var val = (fact.value || '').trim(); | var val = (fact.value || '').trim(); | ||
var label = (fact.label || '').toLowerCase(); | var label = (fact.label || '').toLowerCase(); | ||
if (fact.already_on_page && (field === 'ipw_ge' || field === 'teams')) { | |||
return 'Team already on their profile (' + (val || fact.existing_value || 'same') + ') — no change'; | |||
} | |||
if (fact.already_on_page) { | if (fact.already_on_page) { | ||
return (fact.label || 'Already on page') + ' — skipped'; | return (fact.label || 'Already on page') + ' — skipped'; | ||
} | } | ||
if (field === 'ipw_ge') { | if (field === 'ipw_ge') { | ||
return 'Team | return 'Set their Team (IPW) to ' + val; | ||
} | } | ||
if (field === 'teams') { | if (field === 'teams') { | ||
return ' | return 'Add ' + val + ' to their Teams list'; | ||
} | } | ||
if (field === 'asn') { | if (field === 'asn') { | ||
return 'ASN | return 'Set ASN to ' + val; | ||
} | } | ||
if (field === 'rank_final') { | if (field === 'rank_final') { | ||
return ' | return 'Set rank to ' + val; | ||
} | } | ||
if (field === 'specialty') { | if (field === 'specialty') { | ||
return ' | return 'Set specialty/role to ' + val; | ||
} | } | ||
if (field === 'class_number') { | if (field === 'class_number') { | ||
return ' | return 'Set class to ' + val; | ||
} | } | ||
if (fact.kind === 'bio') { | if (fact.kind === 'bio') { | ||
return ' | return 'Add to biography: ' + (val.length > 80 ? val.slice(0, 80) + '…' : val); | ||
} | } | ||
if (fact.kind === 'note') { | if (fact.kind === 'note') { | ||
| Line 1,396: | Line 1,399: | ||
} | } | ||
function | function personMetaFromItems(items) { | ||
var | var rank = ''; | ||
var role = ''; | |||
var asn = ''; | |||
var team = ''; | |||
items.forEach(function (f) { | items.forEach(function (f) { | ||
if (f.field === ' | if (f.field === 'rank_final' && f.value && !rank) { | ||
rank = f.value; | |||
} | } | ||
if (f.field === ' | if (f.field === 'specialty' && f.value && !role) { | ||
role = f.value; | |||
} | } | ||
if (f.field === ' | if (f.field === 'asn' && f.value && !asn) { | ||
asn = f.value; | |||
} | } | ||
if ((f.field === 'ipw_ge' || f.field === 'teams') && f.value) { | if ((f.field === 'ipw_ge' || f.field === 'teams') && f.value && !team) { | ||
team = f.value.indexOf('IPW') === 0 ? f.value : ('IPW ' + f.value); | |||
} | } | ||
}); | }); | ||
return | return { rank: rank, role: role, asn: asn, team: team }; | ||
} | } | ||
| Line 1,434: | Line 1,437: | ||
function isWritableFact(fact) { | function isWritableFact(fact) { | ||
return fact.kind === 'field' || fact.kind === 'bio'; | return fact.kind === 'field' || fact.kind === 'bio'; | ||
} | |||
/** Team membership is the main action on multi-person roster docs. */ | |||
function isPrimaryTeamFact(fact) { | |||
return fact.field === 'ipw_ge' || fact.field === 'teams'; | |||
} | |||
function profileUpdateSentence(fact) { | |||
if (!fact || !isPrimaryTeamFact(fact)) { | |||
return changeLineForFact(fact); | |||
} | |||
var val = (fact.value || '').trim(); | |||
if (fact.already_on_page) { | |||
return 'Their profile already lists this team — nothing to write.'; | |||
} | |||
if (fact.field === 'teams') { | |||
return 'On their soldier page, add ' + val + ' under Teams (they already have a different primary team).'; | |||
} | |||
return 'On their soldier page, set Team to IPW ' + val + '.'; | |||
} | } | ||
| Line 1,476: | Line 1,498: | ||
opts = opts || {}; | opts = opts || {}; | ||
var writable = isWritableFact(fact) && !fact.already_on_page; | var writable = isWritableFact(fact) && !fact.already_on_page; | ||
var forceSelected = opts.forceSelected; | |||
var selected = writable && (forceSelected === undefined ? !!fact.selected : !!forceSelected); | |||
var $row = $('<div>', { | var $row = $('<div>', { | ||
'class': 'ocr-fact-row' + | 'class': 'ocr-fact-row' + | ||
(fact.already_on_page ? ' ocr-fact-already' : '') + | (fact.already_on_page ? ' ocr-fact-already' : '') + | ||
(writable ? ' ocr-fact-writable' : ' ocr-fact-note') + | (writable ? ' ocr-fact-writable' : ' ocr-fact-note') + | ||
(isPrimaryTeamFact(fact) ? ' ocr-fact-primary' : ' ocr-fact-secondary') + | |||
(fact.kind === 'note' ? ' ocr-fact-is-note' : ''), | (fact.kind === 'note' ? ' ocr-fact-is-note' : ''), | ||
'data-id': fact.id, | 'data-id': fact.id, | ||
| Line 1,488: | Line 1,513: | ||
var $check = $('<input>', { | var $check = $('<input>', { | ||
type: 'checkbox', | type: 'checkbox', | ||
checked: | checked: selected, | ||
disabled: !writable | disabled: !writable | ||
}); | }); | ||
var $line = $('<span>', { 'class': 'ocr-change-line' }).text(changeLineForFact(fact)); | var $line = $('<span>', { 'class': 'ocr-change-line' }).text( | ||
opts.plainSentence ? profileUpdateSentence(fact) : changeLineForFact(fact) | |||
); | |||
var $val = $('<input>', { | var $val = $('<input>', { | ||
type: 'text', | type: 'text', | ||
| Line 1,503: | Line 1,530: | ||
}); | }); | ||
var $details = $('<details>', { 'class': 'ocr-fact-details' }); | var $details = $('<details>', { 'class': 'ocr-fact-details' }); | ||
$details.append($('<summary>').text('Edit')); | $details.append($('<summary>').text('Edit value')); | ||
$details.append($('<label>').text('Value ').append($val)); | $details.append($('<label>').text('Value ').append($val)); | ||
$details.append($('<span>', { 'class': 'ocr-fact-meta' }).text( | $details.append($('<span>', { 'class': 'ocr-fact-meta' }).text( | ||
(fact.kind || '') + ' · conf ' + (fact.confidence || 0) + '%' | 'field ' + (fact.field || fact.kind || '') + ' · conf ' + (fact.confidence || 0) + '%' | ||
)); | )); | ||
if (writable || fact.already_on_page) { | if (writable || fact.already_on_page) { | ||
| Line 1,527: | Line 1,539: | ||
} else { | } else { | ||
$row.append($line, $tgt, $details); | $row.append($line, $tgt, $details); | ||
} | } | ||
if (!writable) { | if (!writable) { | ||
$row.append($('<input>', { type: 'checkbox', checked: false, 'class': 'ocr-fact-check-hidden' }).hide()); | $row.append($('<input>', { type: 'checkbox', checked: false, 'class': 'ocr-fact-check-hidden' }).hide()); | ||
| Line 1,540: | Line 1,550: | ||
function renderPersonCards($list, proposed, job, onChange) { | function renderPersonCards($list, proposed, job, onChange) { | ||
var grouped = groupFactsByPerson(proposed); | var grouped = groupFactsByPerson(proposed); | ||
var lastGroup = null; | |||
var personIndex = 0; | |||
grouped.order.forEach(function (key) { | grouped.order.forEach(function (key) { | ||
var items = grouped.byPerson[key]; | var items = grouped.byPerson[key]; | ||
var first = items[0] || {}; | var first = items[0] || {}; | ||
var title = first.target_title || ''; | var title = first.target_title || ''; | ||
var | var meta = personMetaFromItems(items); | ||
return isWritableFact(f) && !f.already_on_page; | var groupId = first.group_id || ''; | ||
var teamFacts = items.filter(isPrimaryTeamFact); | |||
var secondary = items.filter(function (f) { | |||
return isWritableFact(f) && !isPrimaryTeamFact(f) && !f.already_on_page; | |||
}); | }); | ||
var notes = items.filter(function (f) { | var notes = items.filter(function (f) { | ||
return f.kind === 'note' | return f.kind === 'note'; | ||
}); | }); | ||
var included = | var teamFact = teamFacts[0]; | ||
var teamDone = teamFact && teamFact.already_on_page; | |||
var teamReady = teamFact && !teamFact.already_on_page && !!(teamFact.value || '').trim(); | |||
var included = !!(title && teamReady && teamFact.selected !== false); | |||
if (groupId && groupId !== lastGroup) { | |||
lastGroup = groupId; | |||
var groupLabel = meta.team | |||
? ('Team ' + meta.team) | |||
: ('Group ' + groupId.replace(/^g/i, '')); | |||
var inGroup = grouped.order.filter(function (k) { | |||
return (grouped.byPerson[k][0] || {}).group_id === groupId; | |||
}).length; | |||
$list.append($('<h3>', { 'class': 'ocr-group-heading' }).text( | |||
groupLabel + ' — ' + inGroup + ' people on this document' | |||
)); | |||
} | |||
personIndex += 1; | |||
var $card = $('<div>', { | var $card = $('<div>', { | ||
'class': 'ocr-person-card' + (title ? ' ocr-person-matched' : ' ocr-person-unresolved'), | 'class': 'ocr-person-card' + | ||
(title ? ' ocr-person-matched' : ' ocr-person-unresolved') + | |||
(teamDone ? ' ocr-person-done' : ''), | |||
'data-person': key | 'data-person': key | ||
}); | }); | ||
var $ | |||
$card.append($('<div>', { 'class': 'ocr-card-step' }).text( | |||
'Person ' + personIndex + ' of ' + grouped.order.length + ' on the scan' | |||
)); | |||
/* 1. Who is on the document (read-only identity) */ | |||
var $who = $('<div>', { 'class': 'ocr-card-who' }); | |||
$who.append($('<div>', { 'class': 'ocr-card-who-label' }).text('On the document')); | |||
$who.append($('<div>', { 'class': 'ocr-card-name' }).text(personDisplayName(first))); | |||
var whoBits = []; | |||
if (meta.rank) { | |||
whoBits.push(meta.rank); | |||
} | |||
if (meta.role) { | |||
whoBits.push(meta.role); | |||
} | |||
if (meta.asn) { | |||
whoBits.push('ASN ' + meta.asn); | |||
} | |||
if (meta.team) { | |||
whoBits.push(meta.team); | |||
} | |||
if (whoBits.length) { | |||
$who.append($('<div>', { 'class': 'ocr-card-meta' }).text(whoBits.join(' · '))); | |||
} | |||
$who.append($('<p>', { 'class': 'ocr-card-hint' }).text( | |||
'Rank, role, and ASN here are from the scan (for matching). They are not written to the wiki unless you open “Also update other fields.”' | |||
)); | |||
$card.append($who); | |||
/* 2. Which wiki profile */ | |||
var $match = $('<div>', { 'class': 'ocr-card-match' }); | |||
$match.append($('<div>', { 'class': 'ocr-card-who-label' }).text('Wiki soldier page')); | |||
var $include = $('<input>', { | var $include = $('<input>', { | ||
type: 'checkbox', | type: 'checkbox', | ||
'class': 'ocr-include', | 'class': 'ocr-include', | ||
checked: included | checked: included | ||
}); | }); | ||
var $tgtShared = $('<input>', { | var $tgtShared = $('<input>', { | ||
type: 'text', | type: 'text', | ||
'class': 'ocr-person-title', | 'class': 'ocr-person-title', | ||
value: title, | value: title, | ||
placeholder: ' | placeholder: 'Type surname or ASN to find their page…' | ||
}); | }); | ||
var $suggest = $('<div>', { 'class': 'ocr-suggest' }).hide(); | var $suggest = $('<div>', { 'class': 'ocr-suggest' }).hide(); | ||
| Line 1,585: | Line 1,644: | ||
$card.removeClass('ocr-person-unresolved').addClass('ocr-person-matched'); | $card.removeClass('ocr-person-unresolved').addClass('ocr-person-matched'); | ||
$matchStatus.empty().append( | $matchStatus.empty().append( | ||
$('<span>').text(' | $('<span>').text('Will update: '), | ||
$('<a>', { href: mw.util.getUrl(title), text: title, target: '_blank' }) | $('<a>', { href: mw.util.getUrl(title), text: title, target: '_blank' }) | ||
); | ); | ||
} else { | } else { | ||
$card.removeClass('ocr-person-matched').addClass('ocr-person-unresolved'); | $card.removeClass('ocr-person-matched').addClass('ocr-person-unresolved'); | ||
$matchStatus.text(' | $matchStatus.text('Pick the matching soldier page before applying.'); | ||
$include.prop('checked', false); | $include.prop('checked', false); | ||
syncPrimaryChecks(); | |||
} | } | ||
if (onChange) { | if (onChange) { | ||
| Line 1,597: | Line 1,657: | ||
} | } | ||
} | } | ||
function syncPrimaryChecks() { | |||
var on = $include.prop('checked') && !!$.trim($tgtShared.val() || ''); | |||
$card.find('.ocr-fact-primary.ocr-fact-writable input[type="checkbox"]').prop('checked', on); | |||
if (!on) { | |||
$card.find('.ocr-fact-secondary.ocr-fact-writable input[type="checkbox"]').prop('checked', false); | |||
} | |||
} | |||
$match.append($matchStatus); | |||
if (title) { | if (title) { | ||
setMatch(title); | setMatch(title); | ||
} else { | } else { | ||
$matchStatus.text(' | $matchStatus.text('Not matched yet — search below or pick a suggestion.'); | ||
} | } | ||
$match | $match.append($tgtShared); | ||
$match.append($suggest); | $match.append($suggest); | ||
bindSoldierTypeahead($tgtShared, $suggest, setMatch); | bindSoldierTypeahead($tgtShared, $suggest, setMatch); | ||
| Line 1,617: | Line 1,684: | ||
if (candidates && candidates.length) { | if (candidates && candidates.length) { | ||
var $pick = $('<select>', { 'class': 'ocr-match-pick' }); | var $pick = $('<select>', { 'class': 'ocr-match-pick' }); | ||
$pick.append($('<option>', { value: '', text: 'Suggested | $pick.append($('<option>', { value: '', text: 'Suggested wiki pages…' })); | ||
candidates.forEach(function (t) { | candidates.forEach(function (t) { | ||
$pick.append($('<option>', { value: t, text: t, selected: t === title })); | $pick.append($('<option>', { value: t, text: t, selected: t === title })); | ||
| Line 1,629: | Line 1,696: | ||
} | } | ||
$card.append($match); | $card.append($match); | ||
/* 3. What changes on that profile (team is the only primary action) */ | |||
var $update = $('<div>', { 'class': 'ocr-card-update' }); | |||
$update.append($('<div>', { 'class': 'ocr-card-who-label' }).text('Change on their profile')); | |||
var $includeRow = $('<label>', { 'class': 'ocr-include-row' }); | |||
$includeRow.append($include); | |||
var $changes = $('<div>', { 'class': 'ocr-card-changes' }); | var $changes = $('<div>', { 'class': 'ocr-card-changes' }); | ||
if (teamFact) { | |||
var $ | var $teamRow = renderChangeRow(teamFact, job, { | ||
$ | hideTargetVisible: true, | ||
$changes.append($ | plainSentence: true, | ||
forceSelected: included && !teamDone | |||
}); | |||
$teamRow.find('.ocr-fact-target').val(title); | |||
$teamRow.find('input[type="checkbox"]').first().addClass('ocr-primary-check').hide(); | |||
$changes.append($teamRow); | |||
var sentence = profileUpdateSentence(teamFact); | |||
$includeRow.append(document.createTextNode(' ' + (teamDone ? sentence : ('Apply this: ' + sentence)))); | |||
} else { | |||
$includeRow.append(document.createTextNode(' No team number found for this person yet.')); | |||
$include.prop('disabled', true); | |||
} | |||
$update.append($includeRow); | |||
$update.append($changes); | |||
$include.on('change', function () { | |||
if ($include.prop('checked') && !$.trim($tgtShared.val() || '')) { | |||
$include.prop('checked', false); | |||
$matchStatus.text('Match a soldier page first, then check Apply.'); | |||
return; | |||
} | |||
if ($include.prop('checked') && teamDone) { | |||
$include.prop('checked', false); | |||
return; | |||
} | |||
syncPrimaryChecks(); | |||
if (onChange) { | |||
onChange(); | |||
} | |||
}); | }); | ||
if ( | |||
if (secondary.length) { | |||
$ | var $moreFields = $('<details>', { 'class': 'ocr-card-more' }); | ||
$moreFields.append($('<summary>').text( | |||
'Also update other fields on their page (' + secondary.length + ') — off by default' | |||
)); | |||
secondary.forEach(function (fact) { | |||
var $row = renderChangeRow(fact, job, { | |||
hideTargetVisible: true, | |||
forceSelected: false | |||
}); | |||
$row.find('.ocr-fact-target').val(title); | |||
$moreFields.append($row); | |||
}); | }); | ||
$update.append($moreFields); | |||
} | } | ||
if (notes.length) { | |||
if ( | var $moreNotes = $('<details>', { 'class': 'ocr-card-more' }); | ||
var $ | $moreNotes.append($('<summary>').text('OCR line / teammates (not written)')); | ||
$ | notes.forEach(function (fact) { | ||
var $row = renderChangeRow(fact, job, { hideTargetVisible: true }); | var $row = renderChangeRow(fact, job, { hideTargetVisible: true }); | ||
$row.find('.ocr-fact-target').val(title); | $row.find('.ocr-fact-target').val(title); | ||
$ | $moreNotes.append($row); | ||
}); | }); | ||
$ | $update.append($moreNotes); | ||
} | } | ||
$ | $card.append($update); | ||
$card.on('change', 'input[type="checkbox"], input.ocr-fact-value', function (ev) { | |||
if ( | if ($(ev.target).hasClass('ocr-include')) { | ||
return; | return; | ||
} | } | ||
if (onChange) { | if (onChange) { | ||
onChange(); | onChange(); | ||
| Line 1,679: | Line 1,781: | ||
var $card = $('<div>', { 'class': 'ocr-person-card ocr-person-matched ocr-single-card' }); | var $card = $('<div>', { 'class': 'ocr-person-card ocr-person-matched ocr-single-card' }); | ||
var title = job.bound_title || ''; | var title = job.bound_title || ''; | ||
$card.append($('<div>', { 'class': 'ocr-card-who-label' }).text('Changes for this soldier page')); | |||
$card.append($('<div>', { 'class': 'ocr-card-name' }).text(title || 'This soldier')); | $card.append($('<div>', { 'class': 'ocr-card-name' }).text(title || 'This soldier')); | ||
if (title) { | if (title) { | ||
| Line 1,699: | Line 1,802: | ||
} | } | ||
primary.forEach(function (fact) { | primary.forEach(function (fact) { | ||
var $row = renderChangeRow(fact, job, { hideTargetVisible: true }); | var $row = renderChangeRow(fact, job, { hideTargetVisible: true, plainSentence: true }); | ||
$row.find('.ocr-fact-target').val(title); | $row.find('.ocr-fact-target').val(title); | ||
$changes.append($row); | $changes.append($row); | ||
}); | }); | ||
skipped.forEach(function (fact) { | if (skipped.length) { | ||
var $skip = $('<details>', { 'class': 'ocr-card-more' }); | |||
$skip.append($('<summary>').text('Already on page (' + skipped.length + ')')); | |||
skipped.forEach(function (fact) { | |||
$skip.append(renderChangeRow(fact, job, { hideTargetVisible: true })); | |||
}); | |||
$changes.append($skip); | |||
} | |||
$card.append($changes); | $card.append($changes); | ||
| Line 1,767: | Line 1,875: | ||
var $panel = $('<div>', { 'class': 'ocr-review-panel ocr-review-v2' }); | var $panel = $('<div>', { 'class': 'ocr-review-panel ocr-review-v2' }); | ||
$panel.append($('<p>').append( | $panel.append($('<p>').append( | ||
$('<strong>').text(job.multi_person ? ' | $('<strong>').text(job.multi_person ? 'One card per person on the scan' : 'Confirm changes, then Apply'), | ||
document.createTextNode(' — nothing is saved until you click Apply.') | document.createTextNode( | ||
job.multi_person | |||
? ' — for each person: confirm the wiki page, then check what to write on their profile (usually just Team). Nothing is saved until Apply.' | |||
: ' — nothing is saved until you click Apply.' | |||
) | |||
)); | )); | ||
| Line 1,774: | Line 1,886: | ||
var ps = job.people_summary; | var ps = job.people_summary; | ||
$panel.append($('<p>', { 'class': 'ocr-people-summary' }).text( | $panel.append($('<p>', { 'class': 'ocr-people-summary' }).text( | ||
(ps.detected || 0) + ' people · ' + | (ps.detected || 0) + ' people on this document · ' + | ||
(ps.matched || 0) + ' matched · ' + | (ps.matched || 0) + ' matched to wiki pages · ' + | ||
(ps.unresolved || 0) + ' need | (ps.unresolved || 0) + ' still need a match · ' + | ||
(ps.already_on_page || 0) + ' already have team' + | (ps.already_on_page || 0) + ' already have this team' + | ||
(ps.teams && ps.teams.length ? (' · teams ' + ps.teams.join(', ')) : '') + | (ps.teams && ps.teams.length ? (' · teams ' + ps.teams.join(', ')) : '') + | ||
(ps.inferred_teams && ps.inferred_teams.length ? (' · inferred ' + ps.inferred_teams.join(', ')) : '') | (ps.inferred_teams && ps.inferred_teams.length ? (' · inferred ' + ps.inferred_teams.join(', ')) : '') | ||
| Line 1,830: | Line 1,942: | ||
var $previewBox = $('<div>', { 'class': 'ocr-apply-preview' }); | var $previewBox = $('<div>', { 'class': 'ocr-apply-preview' }); | ||
$previewBox.append($('<strong>').text('What will change')); | $previewBox.append($('<strong>').text('What will change on soldier pages')); | ||
$previewBox.append($('<p>', { 'class': 'ocr-fact-meta' }).text( | |||
job.multi_person | |||
? 'Only checked “Apply this” team updates (and any extra fields you opened) are listed here.' | |||
: 'Checked items below will be written on Apply.' | |||
)); | |||
var $previewUl = $('<ul>', { 'class': 'ocr-apply-preview-list' }); | var $previewUl = $('<ul>', { 'class': 'ocr-apply-preview-list' }); | ||
$previewBox.append($previewUl); | $previewBox.append($previewUl); | ||
| Line 1,841: | Line 1,958: | ||
return; | return; | ||
} | } | ||
var page = (p.target_title || '').trim(); | |||
if (!page) { | |||
return; | return; | ||
} | } | ||
var who = personDisplayName(p); | var who = personDisplayName(p); | ||
lines.push(who + ' → ' + changeLineForFact(p)); | lines.push(who + ' → page “' + page + '”: ' + changeLineForFact(p)); | ||
}); | }); | ||
$previewUl.empty(); | $previewUl.empty(); | ||
if (!lines.length) { | if (!lines.length) { | ||
$previewUl.append($('<li>', { 'class': 'ocr-fact-meta' }).text('Nothing selected yet.')); | $previewUl.append($('<li>', { 'class': 'ocr-fact-meta' }).text( | ||
job.multi_person | |||
? 'Nothing selected yet. Match a person and check “Apply this” on their card.' | |||
: 'Nothing selected yet.' | |||
)); | |||
} else { | } else { | ||
lines.forEach(function (ln) { | lines.forEach(function (ln) { | ||
| Line 1,859: | Line 1,981: | ||
if (job.multi_person) { | if (job.multi_person) { | ||
var $toolbar = $('<div>', { 'class': 'ocr-multi-toolbar' }); | var $toolbar = $('<div>', { 'class': 'ocr-multi-toolbar' }); | ||
var $selMatched = $('<button>', { type: 'button', text: ' | var $selMatched = $('<button>', { type: 'button', text: 'Apply team for all matched' }); | ||
var $deselUnres = $('<button>', { type: 'button', text: ' | var $deselUnres = $('<button>', { type: 'button', text: 'Clear unmatched' }); | ||
$toolbar.append($selMatched, $deselUnres); | $toolbar.append($selMatched, $deselUnres); | ||
$facts.append($toolbar); | $facts.append($toolbar); | ||
renderPersonCards($list, proposed, job, refreshPreview); | renderPersonCards($list, proposed, job, refreshPreview); | ||
$selMatched.on('click', function () { | $selMatched.on('click', function () { | ||
$list.find('.ocr-person-matched').each(function () { | $list.find('.ocr-person-matched:not(.ocr-person-done)').each(function () { | ||
var $card = $(this); | var $card = $(this); | ||
$card.find('.ocr-include').prop('checked', true).trigger('change'); | $card.find('.ocr-include').prop('checked', true).trigger('change'); | ||
}); | }); | ||
refreshPreview(); | refreshPreview(); | ||
}); | }); | ||
$deselUnres.on('click', function () { | $deselUnres.on('click', function () { | ||
$list.find('.ocr-person-unresolved .ocr-include').prop('checked', false) | $list.find('.ocr-person-unresolved .ocr-include').prop('checked', false).trigger('change'); | ||
refreshPreview(); | refreshPreview(); | ||
}); | }); | ||