Files
workspace/code/fms/demo.html
T
2026-09-06 21:47:57 +08:00

40 lines
24 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>ERP 查询构建器 Demo</title>
<style>
:root{--border:#e5e7eb;--border-strong:#cfd6e2;--text:#20242b;--muted:#7b8491;--primary:#1677ff;--primary-soft:#edf5ff;--bg:#f4f6f8;--danger:#e5484d;--shadow:0 16px 44px rgba(30,41,59,.18)}
*{box-sizing:border-box}body{margin:0;background:var(--bg);color:var(--text);font:14px -apple-system,BlinkMacSystemFont,"Segoe UI","Microsoft YaHei",sans-serif}button,input,select{font:inherit}button{cursor:pointer}
.page{padding:24px;max-width:1500px;margin:auto}.header{height:42px;display:flex;align-items:center;justify-content:space-between;margin-bottom:16px}.title{font-size:20px;font-weight:650}.subtitle{color:var(--muted);font-size:12px;margin-top:4px}
.btn{height:34px;padding:0 13px;background:#fff;border:1px solid var(--border-strong);border-radius:6px;color:#303640;display:inline-flex;align-items:center;gap:6px;white-space:nowrap}.btn:hover{background:#f8fafc;border-color:#aeb9c8}.btn.primary{background:var(--primary);border-color:var(--primary);color:#fff}.btn.primary:hover{background:#0f69e8}.btn.link-btn{border:0;background:transparent;color:var(--primary);padding:0 4px}.btn.danger{color:var(--danger)}
.search-panel,.table-panel{background:#fff;border:1px solid var(--border);border-radius:8px}.search-panel{padding:14px 16px;margin-bottom:14px}.search-line{display:flex;gap:8px;align-items:center}.search{position:relative;flex:1;max-width:680px}.search input{width:100%;height:36px;border:1px solid var(--border-strong);border-radius:6px;padding:0 12px 0 35px;outline:none}.search input:focus{border-color:var(--primary);box-shadow:0 0 0 2px #1677ff16}.search .icon{position:absolute;left:12px;top:7px;color:#8c95a2;font-size:18px}.badge{padding:2px 7px;border-radius:10px;background:#dcecff;color:var(--primary);font-size:12px}.query-summary{display:flex;align-items:center;gap:9px;margin-top:10px;min-height:28px}.summary-label{font-size:12px;color:var(--muted);white-space:nowrap}.conditions{display:flex;flex-wrap:wrap;gap:7px;min-width:0}.tag{height:28px;display:flex;align-items:center;gap:5px;border:1px solid #cfe0f8;background:#f7faff;border-radius:5px;padding:0 8px;color:#394454;white-space:nowrap}.tag .label{color:#6f7b89}.tag .x{border:0;background:none;color:#8993a0;padding:0 2px;font-size:16px;line-height:1}.table-head{height:48px;padding:0 16px;display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid #eef0f3}.table-title{font-weight:600}.table-actions{display:flex;align-items:center;gap:10px}.muted{color:var(--muted);font-size:12px}table{width:100%;border-collapse:collapse}th,td{height:48px;padding:0 15px;text-align:left;border-bottom:1px solid #f0f1f3;white-space:nowrap}th{background:#fafbfc;color:#626a76;font-weight:500}tr:hover td{background:#fafcff}.th-label{display:inline-flex;align-items:center;gap:5px}.th-filter{border:0;background:transparent;color:#9aa3ae;padding:3px 2px;font-size:13px}.th-filter:hover{color:var(--primary)}.status{padding:3px 8px;border-radius:4px;background:#fff6df;color:#ad7200;font-size:12px}.link{color:var(--primary);margin-right:14px;cursor:pointer}
.overlay{display:none;position:fixed;inset:0;background:rgba(16,24,40,.32);z-index:20}.overlay.show{display:block}.drawer{position:absolute;right:0;top:0;width:min(820px,100%);height:100%;background:#fff;box-shadow:var(--shadow);display:flex;flex-direction:column}.drawer-head{height:64px;padding:0 22px;border-bottom:1px solid #edf0f3;display:flex;align-items:center;justify-content:space-between}.drawer-title{font-size:16px;font-weight:650}.drawer-title small{display:block;color:var(--muted);font-size:12px;font-weight:400;margin-top:4px}.close{border:0;background:none;color:#89919d;font-size:24px;line-height:1}.drawer-body{padding:18px 22px;overflow:auto;flex:1}.logic-bar{display:flex;align-items:center;gap:8px;padding:10px 12px;background:#f7f9fc;border:1px solid #e8edf3;border-radius:7px;margin-bottom:14px}.logic-bar label{color:#667180;font-size:12px}.logic-bar select{height:30px;border:1px solid var(--border-strong);background:#fff;border-radius:5px;padding:0 28px 0 9px;outline:none}.logic-hint{margin-left:auto;color:var(--muted);font-size:12px}
.builder{display:flex;flex-direction:column;gap:9px}.condition-row{display:grid;grid-template-columns:minmax(185px,1.15fr) 130px minmax(150px,1fr) 28px;gap:8px;align-items:center}.condition-row select,.condition-row input,.field-picker{height:36px;border:1px solid var(--border-strong);border-radius:6px;background:#fff;padding:0 10px;outline:none;min-width:0}.condition-row select:focus,.condition-row input:focus,.field-picker:focus{border-color:var(--primary);box-shadow:0 0 0 2px #1677ff12}.field-picker{width:100%;font-weight:500;color:#303946;text-align:left;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;position:relative;padding-right:28px}.field-picker:after{content:'⌄';position:absolute;right:10px;color:#8792a0}.value-wrap{min-width:0}.value-input{width:100%}.row-values{display:flex;align-items:center;gap:7px}.row-values input{flex:1}.remove-row{height:30px;width:28px;border:0;background:transparent;color:#9aa3ae;font-size:19px;border-radius:4px}.remove-row:hover{background:#fff0f0;color:var(--danger)}.condition-group{border:1px solid #d8e5f5;border-left:3px solid #78aaf1;border-radius:7px;background:#fbfdff;padding:11px 12px}.group-head{display:flex;align-items:center;gap:8px;margin-bottom:9px;color:#607084;font-size:12px}.group-head strong{font-weight:600;color:#40536b}.group-head select{height:28px;border:1px solid var(--border-strong);border-radius:5px;background:#fff;padding:0 24px 0 8px}.group-head .remove-group{margin-left:auto;border:0;background:transparent;color:#8e98a5}.group-rows{display:flex;flex-direction:column;gap:8px}.group-add{margin-top:9px;border:0;background:transparent;color:var(--primary);padding:2px 0}.add-bar{display:flex;align-items:center;gap:16px;margin-top:14px;padding-top:14px;border-top:1px dashed #e0e5eb}.add-bar .btn{height:32px}.field-guide{margin-top:18px;padding:13px 14px;background:#fafbfc;border:1px solid #edf0f3;border-radius:7px}.field-guide-title{font-size:12px;color:#667180;margin-bottom:9px}.quick-fields{display:flex;flex-wrap:wrap;gap:7px}.quick-field{height:28px;border:1px solid #d8e0ea;background:#fff;border-radius:5px;color:#435164;padding:0 9px;font-size:12px}.quick-field:hover{border-color:var(--primary);color:var(--primary);background:var(--primary-soft)}.drawer-foot{padding:13px 22px;border-top:1px solid #edf0f3;text-align:right}.drawer-foot button{margin-left:8px}
.field-pop{display:none;position:fixed;z-index:40;width:300px;max-height:min(520px,calc(100vh - 24px));background:#fff;border:1px solid var(--border);border-radius:8px;box-shadow:var(--shadow);padding:10px}.field-pop.show{display:block}.field-search{width:100%;height:32px;border:1px solid var(--border-strong);border-radius:5px;padding:0 9px;outline:none;margin-bottom:8px}.field-options{max-height:min(455px,calc(100vh - 100px));overflow:auto}.field-section{font-size:11px;color:#8b95a3;padding:7px 7px 4px}.field-option{display:flex;align-items:center;gap:7px;width:100%;height:31px;border:0;background:#fff;text-align:left;padding:0 7px;border-radius:4px;color:#3c4755}.field-option:hover{background:#f3f7fc;color:var(--primary)}.field-option .path{color:#98a2ae;font-size:11px;margin-left:auto}.toast{position:fixed;left:50%;top:25px;transform:translateX(-50%);background:#20242b;color:#fff;padding:9px 16px;border-radius:6px;display:none;z-index:50}.toast.show{display:block}
@media(max-width:760px){.page{padding:12px}.search-line{flex-wrap:wrap}.search{max-width:none;flex-basis:100%}.drawer{width:100%}.condition-row{grid-template-columns:1fr 1fr}.condition-row .value-wrap{grid-column:1 / span 2}.condition-row .remove-row{grid-column:2;justify-self:end;margin-top:-38px}.logic-hint{display:none}.query-summary{align-items:flex-start}.summary-label{padding-top:6px}}
</style>
</head>
<body>
<div class="page">
<div class="header"><div><div class="title">费用列表</div><div class="subtitle">费用单与账单、发票、收付款状态统一查询</div></div><button class="btn primary">+ 新增</button></div>
<div class="search-panel"><div class="search-line"><div class="search"><span class="icon">⌕</span><input id="keyword" placeholder="搜索费用单号、客户、摘要…"></div><button class="btn" id="filterBtn">高级查询 <span class="badge" id="filterBadge">4</span></button><button class="btn primary" id="searchBtn">查询</button><button class="btn" id="resetBtn">重置</button></div><div class="query-summary"><span class="summary-label">当前查询</span><div class="conditions" id="conditions"></div><button class="btn link-btn" id="editQuery">编辑</button></div></div>
<div class="table-panel"><div class="table-head"><span class="table-title">费用数据</span><div class="table-actions"><span class="muted" id="resultText">已应用 4 个条件 · 共 18 条</span><button class="btn">保存视图</button></div></div><table><thead><tr><th width="45">☐</th><th><span class="th-label">费用单号 <button class="th-filter" data-field="expense.no" title="按此列添加条件">⌄</button></span></th><th><span class="th-label">客户 <button class="th-filter" data-field="expense.customer" title="按此列添加条件">⌄</button></span></th><th><span class="th-label">费用类型 <button class="th-filter" data-field="expense.type" title="按此列添加条件">⌄</button></span></th><th><span class="th-label">金额 <button class="th-filter" data-field="expense.amount" title="按此列添加条件">⌄</button></span></th><th><span class="th-label">状态 <button class="th-filter" data-field="expense.status" title="按此列添加条件">⌄</button></span></th><th><span class="th-label">创建时间 <button class="th-filter" data-field="expense.createdAt" title="按此列添加条件">⌄</button></span></th><th>操作</th></tr></thead><tbody><tr><td>□</td><td>FY20260906001</td><td>上海东方物流有限公司</td><td>海运费</td><td>¥12,800.00</td><td><span class="status">待审核</span></td><td>2026-09-06</td><td><span class="link">审核</span><span class="link">详情</span></td></tr><tr><td>□</td><td>FY20260906002</td><td>深圳华南供应链</td><td>港杂费</td><td>¥8,620.00</td><td><span class="status">待审核</span></td><td>2026-09-05</td><td><span class="link">审核</span><span class="link">详情</span></td></tr><tr><td>□</td><td>FY20260906003</td><td>宁波海联国际</td><td>拖车费</td><td>¥4,200.00</td><td><span class="status">已审核</span></td><td>2026-09-05</td><td><span class="link">详情</span></td></tr><tr><td>□</td><td>FY20260906004</td><td>上海东方物流有限公司</td><td>报关费</td><td>¥16,300.00</td><td><span class="status">待审核</span></td><td>2026-09-04</td><td><span class="link">审核</span><span class="link">详情</span></td></tr></tbody></table></div>
</div>
<div class="overlay" id="overlay"><div class="drawer"><div class="drawer-head"><div class="drawer-title">高级查询<small>当前列表列是快捷字段,也可以查询未展示的关联业务字段</small></div><button class="close" id="closeBtn">×</button></div><div class="drawer-body"><div class="logic-bar"><label>满足</label><select id="rootLogic"><option>全部条件(AND)</option><option>任一条件(OR)</option></select><span class="logic-hint">普通列条件与关联单据条件会组合成同一个查询</span></div><div class="builder" id="builder"></div><div class="add-bar"><button class="btn" id="addCondition">+ 添加条件</button><button class="btn" id="addGroup">+ 添加条件组</button></div><div class="field-guide"><div class="field-guide-title">快捷字段 · 点击即可添加</div><div class="quick-fields"><button class="quick-field" data-quick="expense.status">当前费用单 / 状态</button><button class="quick-field" data-quick="expense.amount">当前费用单 / 金额</button><button class="quick-field" data-quick="invoice.status">关联发票 / 发票状态</button><button class="quick-field" data-quick="payment.unpaidAmount">关联收付款 / 未付款金额</button></div></div></div><div class="drawer-foot"><button class="btn" id="drawerReset">重置条件</button><button class="btn" id="cancelBtn">取消</button><button class="btn primary" id="applyBtn">应用查询</button></div></div></div>
<div class="field-pop" id="fieldPop"><input class="field-search" id="fieldSearch" placeholder="搜索字段,例如:发票"><div class="field-options" id="fieldOptions"></div></div><div class="toast" id="toast"></div>
<script>
(function(){
var catalog=[{group:'当前费用单',items:[['expense.no','费用单号'],['expense.customer','客户'],['expense.type','费用类型'],['expense.amount','金额'],['expense.status','状态'],['expense.createdAt','创建时间'],['expense.creator','创建人']]},{group:'关联账单',items:[['bill.exists','账单是否存在'],['bill.status','账单状态'],['bill.amount','账单金额'],['bill.createdAt','账单日期']]},{group:'关联发票',items:[['invoice.exists','发票是否存在'],['invoice.status','发票状态'],['invoice.no','发票号码'],['invoice.amount','发票金额'],['invoice.createdAt','开票日期']]},{group:'关联收付款',items:[['payment.exists','收付款是否存在'],['payment.status','收付款状态'],['payment.unpaidAmount','未付款金额'],['payment.paidAt','付款日期']]}];var fieldMap={};catalog.forEach(function(g){g.items.forEach(function(i){fieldMap[i[0]]={label:i[1],group:g.group};});});var operators={text:[['contains','包含'],['eq','等于'],['ne','不等于'],['isNull','为空']],enum:[['eq','等于'],['ne','不等于'],['in','属于']],number:[['gt','大于'],['ge','大于等于'],['lt','小于'],['le','小于等于'],['between','介于']],date:[['eq','等于'],['ge','不早于'],['le','不晚于'],['between','介于']],exists:[['eq','是']]};var types={no:'text',customer:'text',type:'enum',amount:'number',status:'enum',createdAt:'date',creator:'text',exists:'exists',unpaidAmount:'number',paidAt:'date'};var applied=[{field:'expense.status',op:'eq',value:'待审核'},{field:'expense.amount',op:'gt',value:'10000'},{field:'invoice.status',op:'eq',value:'未开具'},{field:'payment.unpaidAmount',op:'gt',value:'0'}];var draft=[];var overlay=document.getElementById('overlay'),builder=document.getElementById('builder'),conditions=document.getElementById('conditions'),badge=document.getElementById('filterBadge'),resultText=document.getElementById('resultText'),fieldPop=document.getElementById('fieldPop'),fieldOptions=document.getElementById('fieldOptions'),fieldSearch=document.getElementById('fieldSearch'),toast=document.getElementById('toast');
function typeFor(field){return types[field.split('.').pop()]||'text'}function valueOptions(field){var k=field.split('.').pop();if(k==='status')return ['待审核','已审核','已驳回','已生成','未开具','已开具','未付款','部分付款','已付款'];if(k==='type')return ['海运费','港杂费','拖车费','报关费'];return []}function inputHtml(row){var type=typeFor(row.field),opts=valueOptions(row.field);if(type==='enum'||type==='exists')return '<select class="value-input"><option value="">请选择</option>'+opts.map(function(o){return '<option>'+o+'</option>'}).join('')+'</select>';if(type==='date')return '<input class="value-input" type="date">';if(row.op==='between')return '<div class="row-values"><input class="value-input" placeholder="最小值"><span>至</span><input class="value-input" placeholder="最大值"></div>';return '<input class="value-input" placeholder="输入值">'}
function renderBuilder(){builder.innerHTML='';draft.forEach(function(item,index){if(item.kind==='group'){builder.appendChild(makeGroup(item,index))}else builder.appendChild(makeRow(item,index,false))})}function makeFieldButton(row,index,inGroup){var b=document.createElement('button');b.type='button';b.className='field-picker';b.textContent=fieldMap[row.field].group+' / '+fieldMap[row.field].label;b.onclick=function(){openFieldPop(b,row,index,inGroup)};return b}function makeRow(row,index,inGroup){var wrap=document.createElement('div');wrap.className='condition-row';var fs=makeFieldButton(row,index,inGroup);var os=document.createElement('select');os.innerHTML=operators[typeFor(row.field)].map(function(o){return '<option value="'+o[0]+'">'+o[1]+'('+o[0]+')</option>'}).join('');os.value=row.op;os.onchange=function(){row.op=os.value;renderBuilder()};var vw=document.createElement('div');vw.className='value-wrap';vw.innerHTML=inputHtml(row);var inputs=vw.querySelectorAll('.value-input');inputs.forEach(function(inp,i){if(row.value&&inputs.length===1)inp.value=row.value;if(Array.isArray(row.value))inp.value=row.value[i]||'';inp.oninput=function(){row.value=inputs.length===1?inp.value:Array.from(inputs).map(function(x){return x.value})}});var rm=document.createElement('button');rm.className='remove-row';rm.textContent='×';rm.title='删除条件';rm.onclick=function(){if(inGroup)draft.forEach(function(x){if(x.kind==='group'){var n=x.children.indexOf(row);if(n>-1)x.children.splice(n,1)}});else draft.splice(index,1);renderBuilder()};wrap.appendChild(fs);wrap.appendChild(os);wrap.appendChild(vw);wrap.appendChild(rm);return wrap}
function makeGroup(group,index){var box=document.createElement('div');box.className='condition-group';var head=document.createElement('div');head.className='group-head';head.innerHTML='<strong>条件组</strong><span>满足</span>';var logic=document.createElement('select');logic.innerHTML='<option value="and">全部条件(AND)</option><option value="or">任一条件(OR)</option>';logic.value=group.logic||'and';logic.onchange=function(){group.logic=logic.value};head.appendChild(logic);var remove=document.createElement('button');remove.className='remove-group';remove.textContent='删除条件组';remove.onclick=function(){draft.splice(index,1);renderBuilder()};head.appendChild(remove);box.appendChild(head);var rows=document.createElement('div');rows.className='group-rows';group.children.forEach(function(row){rows.appendChild(makeRow(row,index,true))});box.appendChild(rows);var add=document.createElement('button');add.className='group-add';add.textContent='+ 在组内添加条件';add.onclick=function(){group.children.push({field:'invoice.status',op:'eq',value:''});renderBuilder()};box.appendChild(add);return box}
function openFieldPop(anchor,target){var r=anchor.getBoundingClientRect();fieldPop.style.left=Math.min(r.left,window.innerWidth-320)+'px';fieldPop.style.top=Math.min(r.bottom+5,window.innerHeight-390)+'px';fieldPop.classList.add('show');fieldPop._target=target;fieldSearch.value='';renderFieldOptions('');fieldSearch.focus()}function renderFieldOptions(query){var q=query.toLowerCase();fieldOptions.innerHTML='';catalog.forEach(function(g){var items=g.items.filter(function(i){return !q||i[1].toLowerCase().includes(q)||g.group.toLowerCase().includes(q)});if(!items.length)return;var s=document.createElement('div');s.className='field-section';s.textContent=g.group;fieldOptions.appendChild(s);items.forEach(function(i){var b=document.createElement('button');b.className='field-option';b.innerHTML=i[1]+'<span class="path">'+g.group.replace('当前费用单','当前')+'</span>';b.onclick=function(){var target=fieldPop._target;target.field=i[0];target.op=operators[typeFor(i[0])][0][0];target.value='';fieldPop.classList.remove('show');renderBuilder()};fieldOptions.appendChild(b)})})}
function cloneRows(rows){return rows.map(function(r){if(r.kind==='group')return {kind:'group',logic:r.logic,children:cloneRows(r.children)};return {field:r.field,op:r.op,value:Array.isArray(r.value)?r.value.slice():r.value}})}function operatorLabel(op){return {eq:'=',ne:'≠',gt:'>',ge:'≥',lt:'<',le:'≤',contains:'包含',between:'介于',isNull:'为空'}[op]||op}function displayValue(r){if(r.op==='isNull')return '';if(Array.isArray(r.value))return (r.value[0]||'不限')+' 至 '+(r.value[1]||'不限');return r.value||'未设置'}function countConditions(rows){return rows.reduce(function(n,r){return n+(r.kind==='group'?countConditions(r.children):1)},0)}function renderSummary(){conditions.innerHTML='';applied.forEach(function(r){var tag=document.createElement('div');tag.className='tag';if(r.kind==='group'){tag.innerHTML='<span class="label">条件组</span><span>'+countConditions(r.children)+' 个条件 · '+String(r.logic||'and').toUpperCase()+'</span>'}else{tag.innerHTML='<span class="label">'+fieldMap[r.field].label+'</span><span>'+operatorLabel(r.op)+' '+displayValue(r)+'</span>'}var x=document.createElement('button');x.className='x';x.textContent='×';x.onclick=function(){applied.splice(applied.indexOf(r),1);renderSummary()};tag.appendChild(x);conditions.appendChild(tag)});var count=countConditions(applied);badge.textContent=count;badge.style.display=count?'inline-block':'none';resultText.textContent='已应用 '+count+' 个条件 · 共 '+(count?18:128)+' 条'}function validRow(r){return r.op==='isNull'||(r.value!==''&&!(Array.isArray(r.value)&&!r.value[0]&&!r.value[1]))}function normalizeRows(rows){var out=[];rows.forEach(function(r){if(r.kind==='group'){var children=normalizeRows(r.children);if(children.length)out.push({kind:'group',logic:r.logic||'and',children:children})}else if(validRow(r))out.push(r)});return cloneRows(out)}function showDrawer(){draft=cloneRows(applied.length?applied:[{field:'expense.status',op:'eq',value:''}]);renderBuilder();overlay.classList.add('show')}function hideDrawer(){overlay.classList.remove('show');fieldPop.classList.remove('show')}
document.getElementById('filterBtn').onclick=showDrawer;document.getElementById('editQuery').onclick=showDrawer;document.getElementById('closeBtn').onclick=hideDrawer;document.getElementById('cancelBtn').onclick=hideDrawer;overlay.onclick=function(e){if(e.target===overlay)hideDrawer()};document.getElementById('addCondition').onclick=function(){draft.push({field:'expense.status',op:'eq',value:''});renderBuilder()};document.getElementById('addGroup').onclick=function(){draft.push({kind:'group',logic:'and',children:[{field:'invoice.status',op:'eq',value:''}]});renderBuilder()};document.querySelectorAll('.quick-field').forEach(function(b){b.onclick=function(){draft.push({field:b.dataset.quick,op:operators[typeFor(b.dataset.quick)][0][0],value:''});renderBuilder()}});document.querySelectorAll('.th-filter').forEach(function(b){b.onclick=function(){draft=cloneRows(applied);draft.push({field:b.dataset.field,op:operators[typeFor(b.dataset.field)][0][0],value:''});renderBuilder();overlay.classList.add('show')}});document.getElementById('drawerReset').onclick=function(){draft=[];renderBuilder()};document.getElementById('applyBtn').onclick=function(){applied=normalizeRows(draft);renderSummary();hideDrawer();showToast('查询条件已应用')};document.getElementById('resetBtn').onclick=function(){document.getElementById('keyword').value='';applied=[];renderSummary();showToast('查询条件已重置')};document.getElementById('searchBtn').onclick=function(){var k=document.getElementById('keyword').value.trim();if(k){resultText.textContent='搜索“'+k+'” · 已应用 '+countConditions(applied)+' 个条件';showToast('正在查询:'+k)}else showToast('请输入关键词,或使用高级查询')};document.getElementById('keyword').onkeydown=function(e){if(e.key==='Enter')document.getElementById('searchBtn').click()};fieldSearch.oninput=function(){renderFieldOptions(fieldSearch.value)};document.addEventListener('click',function(e){if(fieldPop.classList.contains('show')&&!fieldPop.contains(e.target)&&!e.target.classList.contains('field-picker'))fieldPop.classList.remove('show')});function showToast(t){toast.textContent=t;toast.classList.add('show');clearTimeout(window.__t);window.__t=setTimeout(function(){toast.classList.remove('show')},1500)}renderSummary();
})();
</script>
</body>
</html>