Initial commit - Church Music Database
This commit is contained in:
246
legacy-site/documentation/md-files/WORSHIP_LIST_UPDATE.md
Normal file
246
legacy-site/documentation/md-files/WORSHIP_LIST_UPDATE.md
Normal file
@@ -0,0 +1,246 @@
|
||||
# Worship List Update - December 2025
|
||||
|
||||
## Summary of Changes
|
||||
|
||||
This update addresses cross-device synchronization issues, adds drag-and-drop reordering for songs, and rebrands "Worship Planning" to "Worship List" throughout the application.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Main Features Added
|
||||
|
||||
### 1. **Fixed Cross-Device Song Adding** ✅
|
||||
|
||||
- **Problem**: Unable to add songs to worship plans from other devices
|
||||
- **Solution**:
|
||||
- Backend now normalizes all ID comparisons using `.toString()` to handle both numeric IDs (from local storage) and UUID strings (from backend)
|
||||
- Added duplicate detection for song associations (prevents duplicate entries)
|
||||
- POST endpoints now preserve provided IDs from migration instead of always generating new UUIDs
|
||||
|
||||
### 2. **Drag-and-Drop Song Reordering** ✅
|
||||
|
||||
- **New Feature**: Songs in worship plans can now be reordered by:
|
||||
- **Dragging**: Click and drag songs with the ⋮⋮ handle
|
||||
- **Arrows**: Use ▲ ▼ buttons to move songs up or down
|
||||
- **Visual Feedback**:
|
||||
- Songs highlight on hover with purple border
|
||||
- Cursor changes to "grabbing" during drag
|
||||
- Touch-friendly on mobile devices
|
||||
|
||||
### 3. **Worship Planning → Worship List Rebrand** ✅
|
||||
|
||||
- **Changed Throughout**:
|
||||
- Page title: "Worship List"
|
||||
- Navigation menu: "📋 Worship List" (both desktop and mobile)
|
||||
- Home page card: "Worship List"
|
||||
- Documentation files updated
|
||||
- **Icon Change**: 📅 → 📋 (from calendar to clipboard)
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Technical Changes
|
||||
|
||||
### Backend (`backend/server.js`)
|
||||
|
||||
#### ID Normalization (Songs)
|
||||
|
||||
```javascript
|
||||
// POST - Preserve provided IDs
|
||||
const incomingId = req.body.id != null ? req.body.id.toString() : uuid();
|
||||
if (db.songs.find((s) => s.id?.toString() === incomingId)) {
|
||||
return res.status(409).json({ error: "Song ID already exists" });
|
||||
}
|
||||
|
||||
// GET/PUT/DELETE - Normalize comparisons
|
||||
db.songs.find((s) => s.id?.toString() === req.params.id)
|
||||
```
|
||||
|
||||
#### ID Normalization (Profiles, Plans, Associations)
|
||||
|
||||
- All `profile_id`, `plan_id`, `song_id` comparisons now use `.toString()`
|
||||
- Added duplicate prevention for:
|
||||
- `profileSongs` associations
|
||||
- `planSongs` associations
|
||||
|
||||
#### Export Endpoint Fix
|
||||
|
||||
```javascript
|
||||
db.songs.find((s) => s.id?.toString() === ps.song_id?.toString())
|
||||
```
|
||||
|
||||
### Frontend (`frontend/src/App.js`)
|
||||
|
||||
#### Profile Songs Mapping Enhancement
|
||||
|
||||
```javascript
|
||||
export async function getProfileSongs(profileId) {
|
||||
// Map associations to full songs
|
||||
for (const ps of backend) {
|
||||
let song = await localStorageAPI.getSong(ps.song_id);
|
||||
if (!song) {
|
||||
// Fetch from backend if not in local cache
|
||||
const r = await fetch(`${API_BASE}/songs/${ps.song_id}`);
|
||||
if (r.ok) song = await r.json();
|
||||
}
|
||||
if (song) fullSongs.push(song);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Drag-and-Drop Implementation
|
||||
|
||||
```javascript
|
||||
function handleDragStart(e, index) {
|
||||
e.dataTransfer.effectAllowed = "move";
|
||||
e.dataTransfer.setData("text/plain", index.toString());
|
||||
}
|
||||
|
||||
function handleDrop(e, dropIndex) {
|
||||
e.preventDefault();
|
||||
const dragIndex = parseInt(e.dataTransfer.getData("text/plain"));
|
||||
const newSongs = [...chosenSongs];
|
||||
const [removed] = newSongs.splice(dragIndex, 1);
|
||||
newSongs.splice(dropIndex, 0, removed);
|
||||
setChosenSongs(newSongs);
|
||||
}
|
||||
```
|
||||
|
||||
#### Force Migration Button
|
||||
|
||||
- Added "⚙️ Force Full Migration (Associations)" button in Settings
|
||||
- Re-runs migration even when backend not empty
|
||||
- Migrates missing `profileSongs` and `profileSongKeys`
|
||||
|
||||
### Migration Script (`frontend/src/migration.js`)
|
||||
|
||||
#### Key Fixes
|
||||
|
||||
```javascript
|
||||
// Now uses correct localStorage keys
|
||||
const allProfileSongs = JSON.parse(
|
||||
localStorage.getItem(STORAGE_KEYS.PROFILE_SONGS) || "[]"
|
||||
);
|
||||
|
||||
// Keys stored as array entries
|
||||
const profileSongKeysArr = JSON.parse(
|
||||
localStorage.getItem(STORAGE_KEYS.PROFILE_SONG_KEYS) || "[]"
|
||||
);
|
||||
```
|
||||
|
||||
#### Duplicate Prevention
|
||||
|
||||
- Checks existing backend data before posting
|
||||
- Skips songs/profiles/plans already present
|
||||
- Logs skipped items with ⏭️ emoji
|
||||
|
||||
---
|
||||
|
||||
## 📱 User Interface Changes
|
||||
|
||||
### Worship List Page
|
||||
|
||||
- ✨ **New Label**: "Chosen Songs (X) - Drag to reorder or use arrows"
|
||||
- 🎨 **Visual Drag Handle**: ⋮⋮ appears on each song
|
||||
- 🎯 **Hover Effects**: Songs highlight with purple border and shadow
|
||||
- 📊 **Better Feedback**: Order numbers update instantly on reorder
|
||||
|
||||
### Navigation
|
||||
|
||||
- Desktop menu: "📋 Worship List"
|
||||
- Mobile menu: "📋 Worship List"
|
||||
- Consistent branding throughout
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Migration Guide
|
||||
|
||||
### For Existing Users
|
||||
|
||||
1. **Restart Backend**:
|
||||
|
||||
```powershell
|
||||
cd backend
|
||||
node server.js
|
||||
```
|
||||
|
||||
2. **Run Force Migration** (if needed):
|
||||
- Go to **Settings** → switch to **Online Mode**
|
||||
- Scroll to **Data Management** section
|
||||
- Click **"⚙️ Force Full Migration (Associations)"**
|
||||
- This will sync profile songs and keys to backend
|
||||
|
||||
3. **Verify on Other Devices**:
|
||||
- Open app on secondary device
|
||||
- Ensure **Online Mode** with correct backend IP
|
||||
- Profile saved songs should now display
|
||||
- Worship plan songs should be clickable and show titles
|
||||
|
||||
---
|
||||
|
||||
## ✅ Testing Checklist
|
||||
|
||||
- [x] Backend normalizes IDs correctly (songs, profiles, plans)
|
||||
- [x] Profile songs display on other devices
|
||||
- [x] Plan songs display with titles and are clickable
|
||||
- [x] Adding songs to plan works from any device
|
||||
- [x] Drag-and-drop reordering works
|
||||
- [x] Arrow button reordering works
|
||||
- [x] Force migration button copies associations
|
||||
- [x] "Worship List" name appears throughout app
|
||||
- [x] Navigation icons updated (📋 instead of 📅)
|
||||
- [x] Duplicate associations prevented
|
||||
|
||||
---
|
||||
|
||||
## 🐛 Bug Fixes
|
||||
|
||||
1. **404 Errors on Song Lookup**
|
||||
- **Cause**: Numeric IDs (1, 2) not matching string comparisons
|
||||
- **Fix**: All ID comparisons now use `.toString()`
|
||||
|
||||
2. **Empty Profile Song Lists**
|
||||
- **Cause**: Backend had no profileSongs associations
|
||||
- **Fix**: Migration script now migrates associations; Force Migration button added
|
||||
|
||||
3. **Plan Songs Not Showing**
|
||||
- **Cause**: Export endpoint not finding songs with mixed ID types
|
||||
- **Fix**: Normalized comparisons in export logic
|
||||
|
||||
4. **Unable to Add Songs from Other Device**
|
||||
- **Cause**: Duplicate check failing due to ID type mismatch
|
||||
- **Fix**: Duplicate detection now compares stringified IDs
|
||||
|
||||
---
|
||||
|
||||
## 📝 Known Limitations
|
||||
|
||||
1. **Drag-and-Drop on Touch Devices**: HTML5 drag API has limited mobile support; arrow buttons remain primary method on phones/tablets
|
||||
2. **Real-time Order Sync**: Order changes update on save; WebSocket doesn't broadcast reorder events (plan must be refreshed)
|
||||
3. **Migration Required**: Existing users must run Force Migration once to populate backend associations
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Future Enhancements
|
||||
|
||||
- [ ] Real-time collaborative editing (WebSocket song order updates)
|
||||
- [ ] Touch-friendly drag library (React DnD or similar)
|
||||
- [ ] Bulk song import from CSV
|
||||
- [ ] Plan templates and recurring schedules
|
||||
- [ ] Worship list history and version control
|
||||
|
||||
---
|
||||
|
||||
## 📞 Support
|
||||
|
||||
If you encounter issues:
|
||||
|
||||
1. Check backend is running: `http://localhost:5000/api/health`
|
||||
2. Verify Online Mode settings match your backend IP
|
||||
3. Run Force Migration to sync associations
|
||||
4. Clear browser cache and localStorage if data seems stale
|
||||
5. Check browser console for error messages
|
||||
|
||||
---
|
||||
|
||||
**Updated**: November 29, 2025
|
||||
**Version**: 2.1.0
|
||||
**Author**: GitHub Copilot
|
||||
Reference in New Issue
Block a user