refactor(webui): centralize address selections
This commit is contained in:
@@ -11,6 +11,9 @@ import {
|
||||
FormField,
|
||||
LoadingFrame,
|
||||
PasswordField,
|
||||
SegmentedControl,
|
||||
SelectionList,
|
||||
SelectionListItem,
|
||||
StatusBadge,
|
||||
ToggleSwitch,
|
||||
hasScope,
|
||||
@@ -1791,10 +1794,10 @@ export default function AddressBookPage({ settings, auth, onAuthChange }: Props)
|
||||
function renderContactRow(contact: Contact) {
|
||||
const selected = selectedContactId === contact.id;
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
<SelectionListItem
|
||||
key={contact.id}
|
||||
className={`address-contact-row ${selected ? "is-selected" : ""} ${contact.deleted_at ? "is-archived-row" : ""}`}
|
||||
selected={selected}
|
||||
className={`address-contact-row ${contact.deleted_at ? "is-archived-row" : ""}`}
|
||||
draggable={!contact.deleted_at && !saving}
|
||||
onClick={() => setSelectedContactId(contact.id)}
|
||||
onDragStart={(event) => handleContactDragStart(event, contact)}>
|
||||
@@ -1805,7 +1808,7 @@ export default function AddressBookPage({ settings, auth, onAuthChange }: Props)
|
||||
<span className="address-contact-row-meta">
|
||||
{contact.deleted_at ? <StatusBadge status="archived" /> : contact.tags.slice(0, 2).map((tag) => <span key={tag} className="address-tag">{tag}</span>)}
|
||||
</span>
|
||||
</button>
|
||||
</SelectionListItem>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1981,10 +1984,12 @@ export default function AddressBookPage({ settings, auth, onAuthChange }: Props)
|
||||
{selectedBook?.read_only && <StatusBadge status="read-only" />}
|
||||
{selectedBook?.deleted_at && <StatusBadge status="archived" />}
|
||||
</div>
|
||||
<div className="address-contact-list" role="list">
|
||||
<div className="address-contact-list">
|
||||
{visibleContacts.length === 0 ?
|
||||
<div className="address-empty-note">{selectedBook ? "No contacts found." : "Select an address book."}</div> :
|
||||
visibleContacts.map(renderContactRow)
|
||||
<SelectionList label="Contacts" className="address-contact-selection-list">
|
||||
{visibleContacts.map(renderContactRow)}
|
||||
</SelectionList>
|
||||
}
|
||||
</div>
|
||||
</section>
|
||||
@@ -2267,14 +2272,18 @@ export default function AddressBookPage({ settings, auth, onAuthChange }: Props)
|
||||
</FormField>
|
||||
}
|
||||
{cardDavDiscovery.length > 0 &&
|
||||
<div className="address-sync-result-list">
|
||||
<SelectionList label="Discovered CardDAV address books" className="address-sync-result-list">
|
||||
{cardDavDiscovery.map((item) => (
|
||||
<button type="button" className="address-sync-result-row" key={item.collection_url} onClick={() => useDiscoveredCardDavBook(item)}>
|
||||
<SelectionListItem
|
||||
selected={cardDavForm.collection_url === item.collection_url}
|
||||
className="address-sync-result-row"
|
||||
key={item.collection_url}
|
||||
onClick={() => useDiscoveredCardDavBook(item)}>
|
||||
<strong>{item.display_name || item.collection_url}</strong>
|
||||
<small>{item.collection_url}</small>
|
||||
</button>
|
||||
</SelectionListItem>
|
||||
))}
|
||||
</div>
|
||||
</SelectionList>
|
||||
}
|
||||
</form>
|
||||
</Dialog>
|
||||
@@ -2450,15 +2459,20 @@ export default function AddressBookPage({ settings, auth, onAuthChange }: Props)
|
||||
<strong>{row.field}</strong>
|
||||
<span>{row.local}</span>
|
||||
<span>{row.remote}</span>
|
||||
<span className="address-conflict-choice">
|
||||
<div>
|
||||
{canMergeConflict(conflictDialog) ?
|
||||
<>
|
||||
<button type="button" className={conflictMergeChoices[row.field] !== "remote" ? "is-selected" : ""} onClick={() => setConflictMergeChoice(row.field, "local")}>Local</button>
|
||||
<button type="button" className={conflictMergeChoices[row.field] === "remote" ? "is-selected" : ""} onClick={() => setConflictMergeChoice(row.field, "remote")}>Remote</button>
|
||||
</> :
|
||||
<SegmentedControl<ConflictMergeChoice>
|
||||
className="address-conflict-choice"
|
||||
role="group"
|
||||
size="equal"
|
||||
ariaLabel={`Source for ${row.field}`}
|
||||
options={[{ id: "local", label: "Local" }, { id: "remote", label: "Remote" }]}
|
||||
value={conflictMergeChoices[row.field] ?? "local"}
|
||||
onChange={(choice) => setConflictMergeChoice(row.field, choice)}
|
||||
/> :
|
||||
"—"
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user