|
9 | 9 | import { onMount } from 'svelte'; |
10 | 10 | import PersonCard from './PersonCard.svelte'; |
11 | 11 | import AddPersonInline from './AddPersonInline.svelte'; |
12 | | - import StagedPeople from './StagedPeople.svelte'; |
13 | | - import { fetchOrgAffiliations, crawlTeam, type CrawledPerson } from './lib/org-client'; |
| 12 | + import { fetchOrgAffiliations } from './lib/org-client'; |
| 13 | + import { submitCrawl } from './lib/search-queue'; |
14 | 14 | import type { AffiliatedPerson } from './lib/types'; |
15 | 15 |
|
16 | 16 | let { |
|
30 | 30 | let error = $state<string | null>(null); |
31 | 31 | let expanded = $state<string | null>(null); // person_uuid |
32 | 32 |
|
33 | | - // didi's team crawl (v1.2) — staged candidates, never auto-written. |
34 | | - let crawling = $state(false); |
| 33 | + // didi's team crawl — enqueued as an async job; candidates land as a card |
| 34 | + // in the search-results rail (staging + accept gates live there now, per |
| 35 | + // the Search-Results-Queue-Remote spec). The transient note is the only |
| 36 | + // local feedback the door needs. |
| 37 | + let queued = $state(false); |
35 | 38 | let crawlError = $state<string | null>(null); |
36 | | - let crawlGen = $state(0); // bumps per crawl so StagedPeople remounts fresh |
37 | | - let staged = $state<{ |
38 | | - people: CrawledPerson[]; |
39 | | - filtered_note: string; |
40 | | - source_urls: string[]; |
41 | | - } | null>(null); |
42 | 39 |
|
43 | 40 | async function crawl() { |
44 | | - crawling = true; |
45 | 41 | crawlError = null; |
46 | 42 | try { |
47 | | - const r = await crawlTeam(org_slug, client); |
48 | | - staged = r; |
49 | | - crawlGen += 1; |
50 | | - if (!open) toggle(); |
| 43 | + await submitCrawl({ org_slug, display_name: orgName, target: 'team', client }); |
| 44 | + queued = true; |
| 45 | + setTimeout(() => (queued = false), 5_000); |
51 | 46 | } catch (err) { |
52 | 47 | crawlError = err instanceof Error ? err.message : String(err); |
53 | | - } finally { |
54 | | - crawling = false; |
55 | 48 | } |
56 | 49 | } |
57 | 50 |
|
|
74 | 67 | } |
75 | 68 |
|
76 | 69 | function onEntityUpdated(e: Event) { |
77 | | - const detail = (e as CustomEvent).detail as { person_uuid?: string } | undefined; |
78 | | - if (detail?.person_uuid && loaded && people.some((p) => p.person_uuid === detail.person_uuid)) { |
| 70 | + const detail = (e as CustomEvent).detail as { person_uuid?: string; org_slug?: string } | undefined; |
| 71 | + if (!loaded) return; |
| 72 | + if (detail?.person_uuid && people.some((p) => p.person_uuid === detail.person_uuid)) { |
79 | 73 | void load(); |
| 74 | + return; |
80 | 75 | } |
| 76 | + // Org-shaped events cover the search rail's team accepts (TeamAccept |
| 77 | + // writes person + affiliation, then broadcasts with the org_slug). |
| 78 | + if (detail?.org_slug && detail.org_slug === org_slug) void load(); |
81 | 79 | } |
82 | 80 |
|
83 | 81 | // A new org card means fresh people — reset and lazy-load on next reveal. |
|
86 | 84 | people = []; |
87 | 85 | loaded = false; |
88 | 86 | expanded = null; |
89 | | - staged = null; |
90 | 87 | crawlError = null; |
91 | 88 | if (open) void load(); |
92 | 89 | }); |
|
108 | 105 | <button |
109 | 106 | type="button" |
110 | 107 | class="ow-plus" |
111 | | - title="didi: crawl the web for relevant team members (selection per the relevance brief)" |
112 | | - disabled={crawling} |
| 108 | + title="didi: crawl the web for relevant team members (selection per the relevance brief) — lands in the search queue" |
113 | 109 | onclick={crawl} |
114 | 110 | > |
115 | | - {crawling ? '…' : '🤖'} |
| 111 | + 🤖 |
116 | 112 | </button> |
117 | 113 | </span> |
118 | 114 | </header> |
119 | | - {#if crawling}<p class="ow-empty">didi is crawling for team members — this takes a minute…</p>{/if} |
| 115 | + {#if queued}<p class="ow-empty">team search queued — it lands in the 🔎 search rail when done; keep working</p>{/if} |
120 | 116 | {#if crawlError}<div class="ow-error">{crawlError}</div>{/if} |
121 | 117 |
|
122 | 118 | {#if open} |
|
151 | 147 | {/each} |
152 | 148 | </ul> |
153 | 149 | {/if} |
154 | | - {#if staged} |
155 | | - {#key crawlGen} |
156 | | - <StagedPeople |
157 | | - {org_slug} |
158 | | - {orgName} |
159 | | - {client} |
160 | | - people={staged.people} |
161 | | - filtered_note={staged.filtered_note} |
162 | | - source_urls={staged.source_urls} |
163 | | - onchanged={load} |
164 | | - onclear={() => (staged = null)} |
165 | | - /> |
166 | | - {/key} |
167 | | - {/if} |
168 | 150 | <AddPersonInline {org_slug} {orgName} {client} onadded={load} /> |
169 | 151 | {/if} |
170 | 152 | {/if} |
|
0 commit comments