geoproject-app/IMPLEMENTATION_SUMMARY.md

244 lines
8.5 KiB
Markdown
Raw Permalink Normal View History

# Map Editor Plugin Transformation - Implementation Summary
## Overview
Successfully transformed the map-editor plugin to use Kirby subpages for markers instead of YAML storage. Markers are now fully-featured Kirby pages with extensible block content.
## Changes Implemented
### 1. Backend Infrastructure
#### New Files Created
**`/public/site/plugins/map-editor/api/routes.php`**
- Implements 5 API endpoints:
- `GET /api/map-editor/pages/:pageId/markers` - List all markers for a map page
- `POST /api/map-editor/pages/:pageId/markers` - Create new marker
- `PATCH /api/map-editor/pages/:pageId/markers/:markerId` - Update marker position (multi mode)
- `DELETE /api/map-editor/pages/:pageId/markers/:markerId` - Delete marker
- `PATCH /api/map-editor/pages/:pageId/position` - Update position (single mode)
- All endpoints include:
- Authentication checks
- CSRF token verification
- Permission checks (read/create/update/delete)
- Proper HTTP status codes
- Error handling
**`/public/site/blueprints/pages/marker.yml`**
- Two-tab structure:
- **Content tab**: Title + extensible blocks field (heading, text, image, list, quote)
- **Position tab**:
- Left column: latitude/longitude number fields
- Right column: map-editor in single mode for visual positioning
**`/public/site/plugins/map-editor/src/composables/useMarkersApi.js`**
- Replaces old YAML-based useMarkers.js
- Provides reactive API interface:
- `fetchMarkers()` - Load markers from API
- `createMarker(position)` - Create new marker
- `updateMarkerPosition(markerId, position)` - Update position
- `deleteMarker(markerId)` - Delete marker
- Includes loading states, error handling, CSRF management
#### Modified Files
**`/public/site/plugins/map-editor/index.php`**
- Registered API routes
- Added new field props: `mode`, `latitude`, `longitude`
**`/public/site/blueprints/pages/map.yml`**
- Added markers section to sidebar:
- Type: pages
- Template: marker
- Sorted by num (Kirby's built-in ordering)
**`/public/site/plugins/map-editor/src/composables/useMapData.js`**
- Removed all marker-related logic
- `saveMapData()` now only saves: background, center, zoom
- Removed markers parameter from function signatures
### 2. Frontend Refactoring
**`/public/site/plugins/map-editor/src/components/field/MapEditor.vue`**
Major refactor with two distinct modes:
#### Multi Mode (default)
- Displays MarkerList sidebar
- Loads markers via API on mount
- Create marker: `handleAddMarker()` → API call
- Delete marker: `deleteMarker()` → API call with confirmation
- Edit marker: `editMarker()` → Redirects to Kirby Panel
- Drag marker: `handleMarkerMoved()` → API call to update position
- Automatically fetches markers from subpages
#### Single Mode (for marker blueprint)
- Hides MarkerList sidebar
- Creates single marker from `latitude`/`longitude` props
- Displays marker at current page coordinates
- Drag marker: Updates page via `/api/map-editor/pages/:pageId/position` endpoint
- Watches latitude/longitude props to update map when fields change
- Smaller height (400px vs 600px)
### 3. Removed Files
- `/public/site/plugins/map-editor/src/components/map/MarkerEditor.vue` - Modal editor no longer needed (Panel handles editing)
- `/public/site/plugins/map-editor/src/composables/useMarkers.js` - Replaced by useMarkersApi.js
## Data Flow
### Multi Mode (Map Page)
1. User opens map page in Panel
2. MapEditor fetches markers via `GET /api/map-editor/pages/:pageId/markers`
3. Markers displayed on map + in sidebar
4. User actions:
- Click "Add" or click map → `POST /api/.../markers` → New subpage created
- Drag marker → `PATCH /api/.../markers/:markerId` → Position updated
- Click "Edit" → Redirect to Panel marker page
- Click "Delete" → `DELETE /api/.../markers/:markerId` → Subpage deleted
5. Changes to center/zoom → Saved to mapdata YAML
### Single Mode (Marker Page)
1. User opens marker page in Panel
2. MapEditor receives latitude/longitude from blueprint query (`{{ page.latitude }}`)
3. Creates visual marker at those coordinates
4. User drags marker → `PATCH /api/map-editor/pages/:pageId/position` → Updates latitude/longitude fields
5. No markers section or CRUD buttons shown
## API Response Format
### GET /api/map-editor/pages/:pageId/markers
```json
{
"status": "success",
"data": {
"markers": [
{
"id": "map/carte/marker-1234567890",
"slug": "marker-1234567890",
"title": "Marqueur 1",
"position": {"lat": 43.8, "lon": 4.3},
"num": 1,
"panelUrl": "/panel/pages/map+carte+marker-1234567890"
}
]
}
}
```
### POST /api/map-editor/pages/:pageId/markers
Request:
```json
{"position": {"lat": 43.8, "lon": 4.3}}
```
Response: Same format as GET, but with single marker
### Error Response
```json
{
"status": "error",
"message": "Error description",
"code": 400
}
```
## Security
- All API endpoints require authentication
- CSRF protection via `X-CSRF` header
- Permission checks (isReadable, can('create'), can('update'), can('delete'))
- Input validation (coordinate ranges, required fields)
- Proper error handling with try/catch
## Marker Ordering
- Uses Kirby's native `num` field for ordering
- Listed subpages sorted by `num asc`
- Panel drag-and-drop automatically manages num
- No custom ordering logic needed
## Migration Notes
- Only one map page exists with fake content → No migration needed
- Old YAML markers structure no longer used
- mapdata field now only stores: background, center, zoom
## Testing Checklist
- [x] API routes created and registered
- [x] Blueprint structure correct
- [x] MapEditor.vue refactored for API
- [x] Single mode implemented
- [x] Old files removed (MarkerEditor.vue, useMarkers.js)
- [ ] Test marker creation from map
- [ ] Test marker deletion with confirmation
- [ ] Test marker drag updates position
- [ ] Test edit button redirects to Panel
- [ ] Test single mode in marker page
- [ ] Test single mode drag updates coordinates
- [ ] Test GeocodeSearch in both modes
- [ ] Test with 50 markers (performance)
- [ ] Verify CSRF protection works
- [ ] Verify permissions are enforced
## Known Considerations
1. **Panel Refresh**: In single mode, when dragging a marker, the API updates the latitude/longitude fields, but the Panel doesn't automatically refresh. Users may need to reload to see updated number values.
2. **Page ID Extraction**: The code extracts page ID from `props.name` with a regex. This works for standard Kirby field names but may need adjustment if field naming changes.
3. **Error Handling**: API errors are logged to console. Consider adding user-visible error messages in the UI.
4. **Loading States**: Loading states are available in the component but not visually displayed. Consider adding a loading spinner.
## Next Steps (Future Improvements)
1. Add visual loading indicators during API calls
2. Add user-visible error messages (toasts/alerts)
3. Implement real-time Panel field sync in single mode
4. Add marker icon customization
5. Add marker search/filter in MarkerList
6. Consider pagination for maps with many markers
7. Add bulk operations (delete multiple, reorder)
8. Add marker clustering on map for better performance
## File Structure After Implementation
```
/public/site/plugins/map-editor/
├── api/
│ └── routes.php (NEW)
├── src/
│ ├── components/
│ │ ├── field/
│ │ │ └── MapEditor.vue (MODIFIED - major refactor)
│ │ └── map/
│ │ ├── MapPreview.vue
│ │ ├── MarkerList.vue
│ │ └── MarkerEditor.vue (DELETED)
│ └── composables/
│ ├── useMarkersApi.js (NEW)
│ ├── useMapData.js (MODIFIED)
│ └── useMarkers.js (DELETED)
└── index.php (MODIFIED)
/public/site/blueprints/pages/
├── marker.yml (NEW)
└── map.yml (MODIFIED)
```
## Summary
The transformation successfully achieves the goal of making markers first-class Kirby content with extensible fields. The implementation:
- ✅ Maintains backward compatibility for map data (center, zoom, background)
- ✅ Provides clean API-based architecture
- ✅ Supports both multi-marker (map page) and single-marker (marker page) modes
- ✅ Leverages Kirby's built-in Panel for content editing
- ✅ Includes proper security and error handling
- ✅ Uses Kirby's native ordering system
- ✅ Removes obsolete YAML-based marker storage
The plugin is now ready for testing and refinement based on real-world usage.