mirror of
https://github.com/warmbly/warmbly.git
synced 2026-09-10 08:06:04 +00:00
feat: fix issue #381 by scoping the import and sheet-sync entry points on a segment's member list to that segment, so a CSV uploaded from inside a segment pins its rows in instead of creating contacts that are nowhere in it, and round the page out with an empty state offering Add contacts, Import file and New contact plus a pinned-contacts panel that says when it is showing only the newest slice of a large import
This commit is contained in:
@@ -127,7 +127,7 @@ function SegmentDetail() {
|
||||
|
||||
{(s.included_count > 0 || s.excluded_count > 0) && <OverridesPanel segment={s} />}
|
||||
|
||||
<ContactsTable key={s.id} segment={{ id: s.id, name: s.name }} />
|
||||
<ContactsTable key={s.id} segment={{ id: s.id, name: s.name, color: s.color }} />
|
||||
|
||||
<SegmentEditor open={editorOpen} onClose={() => setEditorOpen(false)} segment={s} />
|
||||
<AddSegmentToCampaignDialog open={campaignOpen} onClose={() => setCampaignOpen(false)} segment={s} />
|
||||
@@ -190,6 +190,10 @@ function OverridesPanel({ segment }: { segment: Segment }) {
|
||||
}
|
||||
|
||||
const list = overrides.data ?? [];
|
||||
// The API caps one listing, so a segment a big import pinned into shows a
|
||||
// slice of its overrides. Say so rather than implying this is all of them.
|
||||
const pinned = segment.included_count + segment.excluded_count;
|
||||
const truncated = pinned > list.length;
|
||||
return (
|
||||
<div className="border-b border-slate-200 bg-slate-50/40">
|
||||
<button
|
||||
@@ -232,6 +236,12 @@ function OverridesPanel({ segment }: { segment: Segment }) {
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
{truncated && (
|
||||
<li className="px-5 h-9 flex items-center text-[11.5px] text-slate-400">
|
||||
Showing the newest {list.length.toLocaleString()} of {pinned.toLocaleString()}. Search the member
|
||||
list below to reach the rest.
|
||||
</li>
|
||||
)}
|
||||
</ul>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -117,7 +117,7 @@ export default function ContactsTable({
|
||||
}: {
|
||||
current_campaign?: MiniCampaign;
|
||||
// Scope the list to one segment's members (the segment detail page).
|
||||
segment?: { id: string; name: string };
|
||||
segment?: { id: string; name: string; color?: string };
|
||||
}) {
|
||||
const confirm = useConfirm();
|
||||
const segmentMembers = useSetSegmentMembers();
|
||||
@@ -487,7 +487,7 @@ export default function ContactsTable({
|
||||
? "Pick people from your contacts, import a file, or add one by hand. The linked segments could not be loaded."
|
||||
: "Pick people from your contacts, link a segment, import a file, or add one by hand."
|
||||
: segment
|
||||
? "Nobody matches its conditions yet. Adjust them or pin contacts in."
|
||||
? "Nothing matches it yet. Pin people in from your contacts, import a file, or add one by hand."
|
||||
: "Add or upload contacts to get started."
|
||||
}
|
||||
emptyCta={
|
||||
@@ -532,6 +532,29 @@ export default function ContactsTable({
|
||||
Import file
|
||||
</TopbarAction>
|
||||
</div>
|
||||
) : segment ? (
|
||||
<div className="flex flex-wrap items-center justify-center gap-1.5">
|
||||
<TopbarAction
|
||||
icon={<UsersIcon className="w-3 h-3" />}
|
||||
onClick={() => setFromContactsOpen(true)}
|
||||
>
|
||||
Add contacts
|
||||
</TopbarAction>
|
||||
<TopbarAction
|
||||
variant="ghost"
|
||||
icon={<UploadIcon className="w-3 h-3" />}
|
||||
onClick={() => setImportOpen(true)}
|
||||
>
|
||||
Import file
|
||||
</TopbarAction>
|
||||
<TopbarAction
|
||||
variant="ghost"
|
||||
icon={<UserPlusIcon className="w-3 h-3" />}
|
||||
onClick={() => setNewOpen(true)}
|
||||
>
|
||||
New contact
|
||||
</TopbarAction>
|
||||
</div>
|
||||
) : (
|
||||
<TopbarAction
|
||||
icon={<UserPlusIcon className="w-3 h-3" />}
|
||||
@@ -931,8 +954,9 @@ export default function ContactsTable({
|
||||
<ImportWizard
|
||||
open={importOpen}
|
||||
onClose={() => setImportOpen(false)}
|
||||
lockedSegment={segment}
|
||||
/>
|
||||
<SyncSourcesPanel open={syncOpen} onClose={() => setSyncOpen(false)} />
|
||||
<SyncSourcesPanel open={syncOpen} onClose={() => setSyncOpen(false)} segment={segment} />
|
||||
</Page>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user