195 lines
5.5 KiB
Markdown
195 lines
5.5 KiB
Markdown
# User Email Lookup Tool
|
|
|
|
A standalone utility for looking up email addresses from the Associations collection and displaying them as hover tooltips over user names in the sharing interface.
|
|
|
|
## Features
|
|
|
|
- 🔍 Email lookup via Associations collection by first name
|
|
- 💬 Hover tooltips show email addresses automatically
|
|
- 🚀 Request caching to minimize PocketBase queries
|
|
- 👁️ Automatic tooltip persistence during hover
|
|
- 📍 MutationObserver integration for dynamic capsule additions
|
|
- ⚡ Graceful fallback for missing emails
|
|
|
|
## Installation
|
|
|
|
Copy the `user-email-lookup` folder to your project:
|
|
|
|
```bash
|
|
cp -r user-email-lookup /path/to/project/tools/
|
|
```
|
|
|
|
## Usage
|
|
|
|
After the tool is loaded and PocketBase is initialized, call:
|
|
|
|
```javascript
|
|
// Initialize email lookups for note sharing
|
|
window.setupUserEmailLookup(pb, '#selectedUsersContainer');
|
|
|
|
// Or for conversation sharing
|
|
window.setupUserEmailLookup(pb, '#selectedConversationUsersContainer');
|
|
```
|
|
|
|
### Parameters
|
|
|
|
| Parameter | Type | Description |
|
|
| --- | --- | --- |
|
|
| `pb` | PocketBase | Initialized PocketBase client instance |
|
|
| `containerSelector` | string | CSS selector for container with user capsules (e.g., `#selectedUsersContainer`) |
|
|
|
|
## How It Works
|
|
|
|
1. **Initial Setup**: Scans container for existing user capsules and attaches hover listeners
|
|
2. **Dynamic Monitoring**: Uses MutationObserver to detect newly added capsules
|
|
3. **Email Lookup**: On hover, queries Associations collection for `first_name` match
|
|
4. **Caching**: Stores results in memory to prevent redundant queries
|
|
5. **Tooltip Display**: Shows email in native browser tooltip (`title` attribute)
|
|
|
|
### Example User Experience
|
|
|
|
```
|
|
User types: "John, Sarah, Mike"
|
|
System creates capsules with their first names
|
|
User hovers over "John" capsule
|
|
→ Lookup queries Associations for first_name = "John"
|
|
→ Finds: john.smith@company.com
|
|
→ Tooltip shows: "john.smith@company.com"
|
|
User hovers over "Sarah" capsule
|
|
→ Cache hit (if already looked up Sarah recently)
|
|
→ Tooltip shows: "sarah.jones@company.com"
|
|
```
|
|
|
|
## API
|
|
|
|
### `setupUserEmailLookup(pb, containerSelector)`
|
|
|
|
Initialize email lookups for a container of user capsules.
|
|
|
|
```javascript
|
|
window.setupUserEmailLookup(pb, '#selectedUsersContainer');
|
|
```
|
|
|
|
### `getEmailByFirstName(pb, firstName)`
|
|
|
|
Manually lookup an email by first name. Used internally but available for custom extensions.
|
|
|
|
```javascript
|
|
const email = await getEmailByFirstName(pb, 'John');
|
|
// Returns: 'john@example.com' or 'Email not found' or 'Error loading email'
|
|
```
|
|
|
|
### `clearEmailLookupCache()`
|
|
|
|
Clear the in-memory email cache. Useful if Associations collection is updated and you need fresh data.
|
|
|
|
```javascript
|
|
window.clearEmailLookupCache();
|
|
```
|
|
|
|
## Integration
|
|
|
|
This tool is designed for Prism Notes integration. Include it in `index.html`:
|
|
|
|
```html
|
|
<script src="tools/user-email-lookup/index.js"></script>
|
|
```
|
|
|
|
Then initialize after PocketBase auth completes:
|
|
|
|
```javascript
|
|
// In the user auth flow
|
|
if (pb.authStore.isValid) {
|
|
window.setupUserEmailLookup(pb, '#selectedUsersContainer');
|
|
}
|
|
```
|
|
|
|
## PocketBase Requirements
|
|
|
|
Your **Associations** collection must have:
|
|
- `first_name` field (string) — used for lookups
|
|
- `email` field (string) — displayed in tooltip
|
|
|
|
### Example Associations Record
|
|
|
|
```json
|
|
{
|
|
"id": "abc123",
|
|
"first_name": "John",
|
|
"email": "john.smith@company.com",
|
|
"last_name": "Smith",
|
|
"created": "2026-01-14T...",
|
|
"updated": "2026-01-14T..."
|
|
}
|
|
```
|
|
|
|
## Caching Behavior
|
|
|
|
**Cache Storage**: In-memory JavaScript object (lost on page refresh)
|
|
|
|
**When to Clear**:
|
|
- After Associations collection updates
|
|
- If user updates their profile
|
|
- Before bulk operations with many lookups
|
|
|
|
**Manual Clear**:
|
|
```javascript
|
|
window.clearEmailLookupCache();
|
|
```
|
|
|
|
## Browser Compatibility
|
|
|
|
- Works in all modern browsers (Chrome 90+, Firefox 88+, Safari 14+, Edge 90+)
|
|
- Requires MutationObserver API (widely supported)
|
|
- Uses native `title` attribute for tooltips (no dependencies)
|
|
|
|
## Performance Notes
|
|
|
|
- First lookup for a name: ~100-200ms (network + PocketBase query)
|
|
- Subsequent lookups: <1ms (cache hit)
|
|
- Memory usage: ~100 bytes per cached name
|
|
- MutationObserver overhead: Negligible
|
|
|
|
## Troubleshooting
|
|
|
|
### "Email not found" tooltip
|
|
Check that:
|
|
1. Associations collection exists in PocketBase
|
|
2. `first_name` field is spelled correctly
|
|
3. User's record has the `first_name` populated
|
|
4. PocketBase read rules allow access to Associations collection
|
|
|
|
### Slow tooltips on first hover
|
|
This is expected—first lookup queries PocketBase. Subsequent hovers are instant (cached).
|
|
|
|
### "Error loading email" tooltip
|
|
Check PocketBase console for errors. Possible causes:
|
|
- Network connectivity issues
|
|
- Insufficient permissions to read Associations
|
|
- PocketBase server downtime
|
|
|
|
### Cache not clearing
|
|
Cache is in-memory only. Refresh the page to clear, or call:
|
|
```javascript
|
|
window.clearEmailLookupCache();
|
|
```
|
|
|
|
## Future Enhancements
|
|
|
|
- [ ] Persistent storage (IndexedDB) for longer-lived cache
|
|
- [ ] Configurable tooltip styling (custom CSS instead of native title)
|
|
- [ ] Bulk email lookup for performance optimization
|
|
- [ ] Email suggestion/autocomplete during input
|
|
- [ ] Fallback email patterns (first.last@company.com)
|
|
|
|
## Dependencies
|
|
|
|
- `pocketbase` (passed in as parameter) — for Associations queries
|
|
- Browser APIs: DOM, MutationObserver, title attribute
|
|
|
|
## Notes
|
|
|
|
- Tooltips use native browser `title` attribute for simplicity and accessibility
|
|
- Lookup is by `first_name` only (not full name) to match how names are entered in the UI
|
|
- Cache is intentionally in-memory to support real-time Associations updates
|