deploy frontend rebuild v3
CI / compose (push) Successful in 12m55s

This commit is contained in:
Marco0300
2026-09-04 10:20:24 +02:00
parent 39dadd6135
commit 2ccacebdeb
5 changed files with 96 additions and 8 deletions
+11
View File
@@ -329,5 +329,16 @@
['sourceFilter','geographyFilter','categoryFilter','contactStatusFilter','scoreFilter','statusFilter','websiteClassFilter','pipelineFilter'].forEach(id=>$(id)?.addEventListener('change',()=>{page=1;loadData();}));
$('interactionForm').addEventListener('submit',saveInteraction);$('suppressionForm').addEventListener('submit',addSuppression);$('aiProviderForm').addEventListener('submit',saveAiProviderSettings);$('aiProvider').addEventListener('change',updateAiProviderForm);$('aiProviderRefreshBtn').addEventListener('click',loadAiProviderSettings);$('testAiProviderBtn').addEventListener('click',testAiProviderConnection);$('crmRefreshBtn').addEventListener('click',()=>{loadCrmPipeline();loadInteractions(selectedId);});$('reportsRefreshBtn').addEventListener('click',loadReports);$('suppressionRefreshBtn').addEventListener('click',loadSuppressions);$('pipelineViewToggle').addEventListener('click',()=>{crmListMode=!crmListMode;$('pipelineViewToggle').textContent=crmListMode?'▦ Board view':'☷ List view';$('pipelineViewToggle').setAttribute('aria-pressed',String(crmListMode));renderPipeline();});$('pipelineBoard').addEventListener('click',e=>{const selectButton=e.target.closest?.('[data-crm-select]');if(selectButton){selectedId=Number(selectButton.dataset.crmSelect);selectProspect(selectedId);loadInteractions(selectedId);$('crmActivity').scrollIntoView({behavior:'smooth',block:'start'});}const stageButton=e.target.closest?.('[data-crm-save-stage]');if(stageButton)saveCrmStage(stageButton.dataset.crmSaveStage);if(e.target.id==='retryCrmBtn')loadCrmPipeline();if(e.target.id==='retryInteractionsBtn'&&selectedId)loadInteractions(selectedId);});$('suppressionState').addEventListener('change',e=>{const input=e.target.closest?.('[data-suppression-id]');if(input){if(input.checked)selectedSuppressionIds.add(String(input.dataset.suppressionId));else selectedSuppressionIds.delete(String(input.dataset.suppressionId));updateSuppressionSelection();}});$('suppressionState').addEventListener('click',e=>{const button=e.target.closest?.('[data-remove-suppression]');if(button)removeSuppression(button.dataset.removeSuppression);if(e.target.id==='retrySuppressionsBtn')loadSuppressions();});$('selectAllSuppressions').addEventListener('change',e=>{suppressions.forEach(item=>e.target.checked?selectedSuppressionIds.add(String(item.id)):selectedSuppressionIds.delete(String(item.id)));renderSuppressions();});$('bulkReviewSuppressionsBtn').addEventListener('click',bulkReviewSuppressions);$('discoveryWorkspace').addEventListener('click',e=>{const action=e.target.closest?.('[data-run-action]');if(action){const run=discoveryRuns.find(item=>String(item.id)===String(selectedDiscoveryRunId));discoveryAction(action.dataset.runAction,run);}});
$('aiProviderForm').addEventListener('submit',saveAiProviderSettings);$('aiProvider').addEventListener('change',updateAiProviderForm);$('aiProviderRefreshBtn').addEventListener('click',loadAiProviderSettings);$('testAiProviderBtn').addEventListener('click',testAiProviderConnection);$('crmRefreshBtn').addEventListener('click',()=>{loadCrmPipeline();loadInteractions(selectedId);});$('reportsRefreshBtn').addEventListener('click',loadReports);$('suppressionRefreshBtn').addEventListener('click',loadSuppressions);$('pipelineViewToggle').addEventListener('click',()=>{crmListMode=!crmListMode;$('pipelineViewToggle').textContent=crmListMode?'▦ Board view':'☷ List view';$('pipelineViewToggle').setAttribute('aria-pressed',String(crmListMode));renderPipeline();});$('pipelineBoard').addEventListener('click',e=>{const selectButton=e.target.closest?.('[data-crm-select]');if(selectButton){selectedId=Number(selectButton.dataset.crmSelect);selectProspect(selectedId);loadInteractions(selectedId);$('crmActivity').scrollIntoView({behavior:'smooth',block:'start'});}const stageButton=e.target.closest?.('[data-crm-save-stage]');if(stageButton)saveCrmStage(stageButton.dataset.crmSaveStage);if(e.target.id==='retryCrmBtn')loadCrmPipeline();if(e.target.id==='retryInteractionsBtn'&&selectedId)loadInteractions(selectedId);});$('suppressionState').addEventListener('change',e=>{const input=e.target.closest?.('[data-suppression-id]');if(input){if(input.checked)selectedSuppressionIds.add(String(input.dataset.suppressionId));else selectedSuppressionIds.delete(String(input.dataset.suppressionId));updateSuppressionSelection();}});$('suppressionState').addEventListener('click',e=>{const button=e.target.closest?.('[data-remove-suppression]');if(button)removeSuppression(button.dataset.removeSuppression);if(e.target.id==='retrySuppressionsBtn')loadSuppressions();});$('selectAllSuppressions').addEventListener('change',e=>{suppressions.forEach(item=>e.target.checked?selectedSuppressionIds.add(String(item.id)):selectedSuppressionIds.delete(String(item.id)));renderSuppressions();});$('bulkReviewSuppressionsBtn').addEventListener('click',bulkReviewSuppressions);$('outreachPolicyRefreshBtn').addEventListener('click',loadProviderPolicy);
const viewMap = {dashboard:'dashboard', explorer:'prospects', add:'add', discoveryWorkspace:'discovery', jobs:'jobs', sources:'sources', crmPipeline:'crm', crmActivity:'crm', crmReports:'crm', suppressionCenter:'settings', outreachSettings:'settings', aiProviderSettings:'settings', scoreRules:'dashboard'};
function activateView(view) { document.body.dataset.view = view; document.querySelectorAll('.content > section').forEach(section => section.classList.toggle('view-active', viewMap[section.id] === view)); window.scrollTo({top:0, behavior:'smooth'}); }
document.body.dataset.view = 'dashboard';
const sourceSetup = document.querySelector('.source-config-panel');
if (sourceSetup) {
const badge = sourceSetup.querySelector('.small-label');
const copy = sourceSetup.querySelector('.source-setup-copy');
if (badge) badge.textContent = 'Public and operator-controlled sources';
if (copy) copy.textContent = 'Register bounded public sources or operator-controlled imports. New sources start disabled and must be tested before use.';
}
document.querySelectorAll('.sidebar nav a, [data-scroll]').forEach(link => link.addEventListener('click', event => { const target = (link.getAttribute('href') || link.dataset.scroll || '').replace(/^#/, ''); const view = viewMap[target]; if (view) { event.preventDefault(); activateView(view); document.querySelector('.sidebar')?.classList.remove('open'); } }));
bootstrap();
})();
+5 -5
View File
@@ -1,6 +1,6 @@
{
"schema": 1,
"version": "phase-20",
"version": "phase-21",
"entrypoints": [
"config.js",
"app.js",
@@ -13,10 +13,10 @@
"healthz"
],
"integrity": {
"config.js": "sha256-12a10f772029a5ee6d813ed9fd61dfc7ff877aa356bf90f65987948cc3274f90",
"app.js": "sha256-eef64a4296ec8dea6802937af88269b9f759de72fb793f706ac05d30549fcec9",
"styles.css": "sha256-ddbb75572a2e80e19a99834a8fb61540e0d94fffe4658429c99116242034183c",
"index.html": "sha256-2cba8095f33d9eaed8d73c33eecb08b82b223448240e9ef0d96de8c836122da8",
"config.js": "sha256-247380b078f895f025229d42c4f680285a237c498c248cd721f32938ec2398d6",
"app.js": "sha256-8927dd32aa1b79eb9cfa5f58e8ab100927dc3a839a1036774540e475c74626dc",
"styles.css": "sha256-a9fd194b001c0de98775bcf5fbba5da676ccfdd607a889eae84bd30a54c15e08",
"index.html": "sha256-5e6310fe37b241adc4b349dabe5067ad60d56453cbec7c4b1f9b767841c597b1",
"health.html": "sha256-c352a6f37aa24628cfc8d5709a70ff2d94181d192ed5fe00916cca9378a61d81",
"error.html": "sha256-f3cc28d2dfc9e8af112d0257c6ee47b9e9146e5da8590a754dd589bf43702aaf",
"healthz": "sha256-dc51b8c96c2d745df3bd5590d990230a482fd247123599548e0632fdbf97fc22"
+1 -1
View File
@@ -1,5 +1,5 @@
/* Public, non-secret runtime configuration. Replace this file at deploy time if needed. */
window.__PROSPECT_CONFIG__ = Object.freeze({
apiBase: '',
assetVersion: 'phase-20'
assetVersion: 'phase-21'
});
+2 -2
View File
@@ -130,7 +130,7 @@
<div class="merge-dialog" id="mergeDialog" hidden role="dialog" aria-modal="true" aria-labelledby="mergeDialogTitle">
<div class="merge-dialog-card"><div class="panel-heading"><div><p class="eyebrow">REVIEW REQUIRED</p><h2 id="mergeDialogTitle">Confirm merge</h2></div><button class="icon-button" id="cancelMergeBtn" type="button" aria-label="Close merge confirmation">×</button></div><p id="mergeDialogCopy"></p><div class="merge-warning"><strong>This action is reversible.</strong> The merge will be recorded in history and can be reversed later.</div><p id="mergeDialogMessage" class="form-message" role="alert" aria-live="polite"></p><div class="merge-dialog-actions"><button class="button ghost" id="cancelMergeBtnSecondary" type="button">Cancel</button><button class="button primary" id="confirmMergeBtn" type="button">Confirm merge</button></div></div>
</div>
<script src="config.js?v=phase-20"></script>
<script src="app.js?v=phase-20"></script>
<script src="config.js?v=phase-21"></script>
<script src="app.js?v=phase-21"></script>
</body>
</html>
+77
View File
@@ -256,6 +256,83 @@ footer { display: flex; justify-content: space-between; gap: 16px; margin-top: 3
.ai-provider-admin-state { margin: 14px 0; }
.ai-provider-admin-state p { margin: 4px 0 0; }
/* Application views: keep the operator focused on one job at a time. */
body[data-view="dashboard"] .direct-discovery-section,
body[data-view="dashboard"] #explorer,
body[data-view="dashboard"] .jobs-section,
body[data-view="dashboard"] .sources-section,
body[data-view="dashboard"] .lower-grid,
body[data-view="dashboard"] .crm-section { display: none; }
body[data-view="prospects"] #dashboard,
body[data-view="prospects"] #discoveryWorkspace,
body[data-view="prospects"] .metrics,
body[data-view="prospects"] .score-overview,
body[data-view="prospects"] #scoreRules,
body[data-view="prospects"] .jobs-section,
body[data-view="prospects"] .sources-section,
body[data-view="prospects"] .lower-grid,
body[data-view="prospects"] .crm-section { display: none; }
body[data-view="discovery"] #dashboard,
body[data-view="discovery"] .metrics,
body[data-view="discovery"] .score-overview,
body[data-view="discovery"] #scoreRules,
body[data-view="discovery"] #explorer,
body[data-view="discovery"] .jobs-section,
body[data-view="discovery"] .sources-section,
body[data-view="discovery"] .lower-grid,
body[data-view="discovery"] .crm-section { display: none; }
body[data-view="jobs"] #dashboard,
body[data-view="jobs"] .metrics,
body[data-view="jobs"] .score-overview,
body[data-view="jobs"] #scoreRules,
body[data-view="jobs"] #explorer,
body[data-view="jobs"] #discoveryWorkspace,
body[data-view="jobs"] .sources-section,
body[data-view="jobs"] .lower-grid,
body[data-view="jobs"] .crm-section { display: none; }
body[data-view="sources"] #dashboard,
body[data-view="sources"] .metrics,
body[data-view="sources"] .score-overview,
body[data-view="sources"] #scoreRules,
body[data-view="sources"] #explorer,
body[data-view="sources"] #discoveryWorkspace,
body[data-view="sources"] .jobs-section,
body[data-view="sources"] .lower-grid,
body[data-view="sources"] .crm-section { display: none; }
body[data-view="add"] #dashboard,
body[data-view="add"] .metrics,
body[data-view="add"] .score-overview,
body[data-view="add"] #scoreRules,
body[data-view="add"] #explorer,
body[data-view="add"] #discoveryWorkspace,
body[data-view="add"] .jobs-section,
body[data-view="add"] .sources-section,
body[data-view="add"] .crm-section { display: none; }
body[data-view="crm"] #dashboard,
body[data-view="crm"] .metrics,
body[data-view="crm"] .score-overview,
body[data-view="crm"] #scoreRules,
body[data-view="crm"] #explorer,
body[data-view="crm"] #discoveryWorkspace,
body[data-view="crm"] .jobs-section,
body[data-view="crm"] .sources-section,
body[data-view="crm"] .lower-grid { display: none; }
body[data-view="settings"] #dashboard,
body[data-view="settings"] .metrics,
body[data-view="settings"] .score-overview,
body[data-view="settings"] #scoreRules,
body[data-view="settings"] #explorer,
body[data-view="settings"] #discoveryWorkspace,
body[data-view="settings"] .jobs-section,
body[data-view="settings"] .sources-section,
body[data-view="settings"] .lower-grid,
body[data-view="settings"] #crmPipeline,
body[data-view="settings"] #crmActivity,
body[data-view="settings"] #crmReports { display: none; }
#startDemoJobBtn { display: none !important; }
.view-active { animation: view-enter .18s ease-out; }
@keyframes view-enter { from { opacity: .35; transform: translateY(4px); } to { opacity: 1; transform: translateY(0); } }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }
@media (max-width: 1100px) { .metrics { grid-template-columns: repeat(3, 1fr); } .filters { grid-template-columns: repeat(3, 1fr); } .filters .search-wrap { grid-column: 1 / -1; } .workspace-grid { grid-template-columns: 1fr; } .detail-panel { min-height: 0; } .reports-grid { grid-template-columns: 1fr 1fr; } }