This commit addresses multiple collection management issues to improve user experience: ## Template Selection Modal Improvements - Replace inline styles with CSS classes for reliable visual feedback - Fix default template selection conflicts that showed multiple templates as selected - Add styled template previews that show actual CSS styling differences - Improve modal responsiveness and visual hierarchy ## Collection Item Creation Fixes - Fix empty collection items with no content/height that were unclickable - Preserve template placeholder content during item creation instead of clearing it - Implement proper positioning system using GetMaxPosition to place new items at collection end - Add position calculation logic to prevent new items from jumping to beginning ## Backend Positioning System - Add GetMaxPosition method to all repository implementations (SQLite, PostgreSQL, HTTPClient) - Update CreateCollectionItemFromTemplate to calculate correct position (maxPos + 1) - Maintain reconstruction ordering by position ASC for consistent item placement ## Frontend Template Selection - CSS class-based selection states replace problematic inline style manipulation - Template previews now render actual HTML with real page styling - Improved hover states and selection visual feedback - Fixed auto-selection interference with user interaction These changes ensure collection items appear in expected order and template selection provides clear visual feedback with actual styling previews.
113 lines
4.4 KiB
Go
113 lines
4.4 KiB
Go
package db
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
)
|
|
|
|
// ContentRepository interface for accessing content data
|
|
type ContentRepository interface {
|
|
GetContent(ctx context.Context, siteID, contentID string) (*ContentItem, error)
|
|
GetBulkContent(ctx context.Context, siteID string, contentIDs []string) (map[string]ContentItem, error)
|
|
GetAllContent(ctx context.Context, siteID string) (map[string]ContentItem, error)
|
|
CreateContent(ctx context.Context, siteID, contentID, htmlContent, originalTemplate, lastEditedBy string) (*ContentItem, error)
|
|
UpdateContent(ctx context.Context, siteID, contentID, htmlContent, lastEditedBy string) (*ContentItem, error)
|
|
|
|
// Collection operations
|
|
GetCollection(ctx context.Context, siteID, collectionID string) (*CollectionItem, error)
|
|
CreateCollection(ctx context.Context, siteID, collectionID, containerHTML, lastEditedBy string) (*CollectionItem, error)
|
|
GetCollectionItems(ctx context.Context, siteID, collectionID string) ([]CollectionItemWithTemplate, error)
|
|
GetCollectionTemplates(ctx context.Context, siteID, collectionID string) ([]CollectionTemplateItem, error)
|
|
GetCollectionTemplate(ctx context.Context, templateID int) (*CollectionTemplateItem, error)
|
|
CreateCollectionTemplate(ctx context.Context, siteID, collectionID, name, htmlTemplate string, isDefault bool) (*CollectionTemplateItem, error)
|
|
CreateCollectionItem(ctx context.Context, siteID, collectionID, itemID string, templateID int, htmlContent string, position int, lastEditedBy string) (*CollectionItemWithTemplate, error)
|
|
CreateCollectionItemAtomic(ctx context.Context, siteID, collectionID string, templateID int, lastEditedBy string) (*CollectionItemWithTemplate, error)
|
|
GetMaxPosition(ctx context.Context, siteID, collectionID string) (int, error)
|
|
ReorderCollectionItems(ctx context.Context, siteID, collectionID string, items []CollectionItemPosition, lastEditedBy string) error
|
|
|
|
// Transaction support
|
|
WithTransaction(ctx context.Context, fn func(ContentRepository) error) error
|
|
}
|
|
|
|
// ContentItem represents a piece of content from the database
|
|
type ContentItem struct {
|
|
ID string `json:"id"`
|
|
SiteID string `json:"site_id"`
|
|
HTMLContent string `json:"html_content"`
|
|
OriginalTemplate string `json:"original_template"`
|
|
UpdatedAt string `json:"updated_at"`
|
|
LastEditedBy string `json:"last_edited_by,omitempty"`
|
|
}
|
|
|
|
// ContentResponse represents the API response structure
|
|
type ContentResponse struct {
|
|
Content []ContentItem `json:"content"`
|
|
Error string `json:"error,omitempty"`
|
|
}
|
|
|
|
// CollectionItem represents a collection container from the database
|
|
type CollectionItem struct {
|
|
ID string `json:"id"`
|
|
SiteID string `json:"site_id"`
|
|
ContainerHTML string `json:"container_html"`
|
|
UpdatedAt string `json:"updated_at"`
|
|
LastEditedBy string `json:"last_edited_by,omitempty"`
|
|
}
|
|
|
|
// CollectionTemplateItem represents a collection template from the database
|
|
type CollectionTemplateItem struct {
|
|
TemplateID int `json:"template_id"`
|
|
CollectionID string `json:"collection_id"`
|
|
SiteID string `json:"site_id"`
|
|
Name string `json:"name"`
|
|
HTMLTemplate string `json:"html_template"`
|
|
IsDefault bool `json:"is_default"`
|
|
}
|
|
|
|
// CollectionItemWithTemplate represents a collection item with its template information
|
|
type CollectionItemWithTemplate struct {
|
|
ItemID string `json:"item_id"`
|
|
CollectionID string `json:"collection_id"`
|
|
SiteID string `json:"site_id"`
|
|
TemplateID int `json:"template_id"`
|
|
HTMLContent string `json:"html_content"`
|
|
Position int `json:"position"`
|
|
UpdatedAt string `json:"updated_at"`
|
|
LastEditedBy string `json:"last_edited_by"`
|
|
|
|
// Template information
|
|
TemplateName string `json:"template_name"`
|
|
HTMLTemplate string `json:"html_template"`
|
|
IsDefault bool `json:"is_default"`
|
|
}
|
|
|
|
// CollectionItemPosition represents item position for reordering
|
|
type CollectionItemPosition struct {
|
|
ItemID string `json:"itemId"`
|
|
Position int `json:"position"`
|
|
}
|
|
|
|
// Helper function to convert sql.NullString to string
|
|
func getStringFromNullString(ns sql.NullString) string {
|
|
if ns.Valid {
|
|
return ns.String
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// ToNullString converts a string to sql.NullString
|
|
func ToNullString(s string) sql.NullString {
|
|
if s == "" {
|
|
return sql.NullString{Valid: false}
|
|
}
|
|
return sql.NullString{String: s, Valid: true}
|
|
}
|
|
|
|
// FromNullString converts sql.NullString to string
|
|
func FromNullString(ns sql.NullString) string {
|
|
if ns.Valid {
|
|
return ns.String
|
|
}
|
|
return ""
|
|
}
|