Skip to content

Conversation

@bokelley
Copy link
Collaborator

@bokelley bokelley commented Nov 4, 2025

Summary

Implements comprehensive size-based filtering system for creative formats based on selected inventory. This feature makes it much easier for users to select appropriate creative formats by automatically suggesting formats that match the sizes of their selected ad units and placements.

Key Features

Progressive Disclosure UX

  • Show all formats initially - No waiting for inventory selection
  • Contextual filtering - Size chips appear when inventory is selected
  • Visual match indicators - Green dots and highlights on matching formats
  • Quick actions - "Select all matching" button for efficient workflow

Size Extraction Intelligence

  • Extracts sizes from selected ad units directly via metadata (e.g., 300×250, 728×90)
  • For placements, looks up their ad_unit_ids and fetches associated ad unit sizes
  • Handles async data loading for placement ad units not yet cached
  • Displays size counts showing how many inventory items support each dimension

Visual Design

  • Size chips: Blue clickable chips showing dimensions with unit counts (sorted by frequency)
  • Match indicators: Green pulsing dot + highlighted background on matching format cards
  • Inline metadata: Shows sizes for ad units, ad unit counts for placements in selection display
  • Toast notifications: User feedback for actions like "Selected 5 matching formats"

User Workflows Supported

  1. Exploratory: Browse all formats, see which match selected inventory
  2. Quick select: Click "Select all matching" to instantly select compatible formats
  3. Filtered view: Toggle "Show only matching" to hide non-compatible formats
  4. Search: Existing search box still works alongside size filtering

Technical Implementation

Data Flow

1. User selects ad units/placements → applyInventorySelection()
2. Items cached in inventoryCache with full metadata
3. extractSizesFromInventory() called:
   - Extracts sizes from ad units directly
   - For placements, looks up ad_unit_ids and gets those sizes
   - Populates extractedSizes Set and sizeUnitCounts Map
4. updateSizeChipsPanel() creates size chips UI
5. updateFormatMatchIndicators() adds CSS class to matching formats
6. User can interact: "Select all matching" or "Show only matching"

Key Functions Added

  • extractSizesFromInventory() - Async extraction from ad units and placements
  • updateSizeChipsPanel() - Renders sorted size chips with counts
  • updateFormatMatchIndicators() - Adds .matches-inventory CSS class
  • extractSizesFromFormatName() - Parses dimensions from format names
  • updateMatchingFormatsCount() - Updates counter and button text
  • selectAllMatchingFormats() - Quick select functionality
  • toggleShowOnlyMatching() - Filter toggle
  • showToast() - Toast notifications
  • updateHiddenFormatsField() - Form submission helper

Files Modified

  • templates/add_product_gam.html:
    • Added size chips panel UI (lines 104-122)
    • Added ~260 lines of JavaScript functions (lines 1224-1490)
    • Added CSS styling for chips, match indicators, and toasts (lines 1521-1631)
    • Enhanced updateSelectedDisplay() to show sizes/counts inline
    • Updated loadInventory() to cache items with metadata
    • Updated applyInventorySelection() to trigger size extraction

Design Decisions

Why Progressive Disclosure?

Per adtech product expert recommendation: Show all formats initially (don't hide anything), then add contextual help when inventory is selected. This prevents confusion and supports exploration.

Why Visual Indicators vs. Hiding?

Users can see ALL formats and understand which ones match. Hiding creates "where did it go?" confusion. The toggle gives power users an option to filter if they want.

Why "Select All Matching"?

Primary workflow optimization. Users typically want formats that match their inventory. One click gets them 90% of the way there.

Handling 1×1 Native Formats

Per user clarification: "1×1 and native aren't edge cases" - these are first-class formats. The size extraction logic properly handles 1×1 as a valid size, and native formats are parsed from format names.

Testing Notes

✅ All pre-commit hooks passed
✅ Unit tests: 861 passed
✅ Integration tests: 32 passed
✅ Integration_v2 tests: 28 passed

Manual testing recommended:

  1. Create/edit product → select ad units → verify sizes appear
  2. Select placements → verify their ad unit sizes extracted
  3. Verify format match indicators appear
  4. Test "Select all matching" button
  5. Test "Show only matching" toggle
  6. Test with various size combinations (including 1×1)

Screenshots

(Add screenshots when testing in UI)

Related Work

🤖 Generated with Claude Code

bokelley added a commit that referenced this pull request Nov 4, 2025
Fixes the "0 matching" issue where format cards weren't being matched
against inventory sizes.

**Root Cause:**
- Format matching was only looking at text content of format cards
- The actual dimensions are stored in the `data-dimensions` attribute
- This caused zero matches even when compatible formats existed

**Solution:**
- Updated `updateFormatMatchIndicators()` to read `data-dimensions` attribute
- Falls back to extracting from text content if needed
- Now properly identifies matching formats

**Workflow Fix:**
- Moved `updateMatchingFormatsCount()` call into `updateFormatMatchIndicators()`
- Ensures count updates after match indicators are added
- Removed duplicate call from `updateSizeChipsPanel()`

**Result:**
- Format cards now properly show green dots when they match inventory sizes
- "X matching / 38 total formats" counter works correctly
- "Select all matching" button appears when matches exist

Fixes GitHub issue reported in PR #690.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 4, 2025
Removes confusing "Map to Selected Inventory" button and green dot
indicators in favor of a cleaner, simpler interface.

**Changes:**

1. **Removed "Map to Selected Inventory" button**
   - Was confusing being far from the inventory section
   - Auto-mapping logic removed

2. **Added simple Select/Deselect All buttons**
   - "✓ Select All" - selects all visible formats
   - "✗ Deselect All" - deselects all formats
   - Works with "Show only matching" filter (only selects visible)
   - Shows toast notifications for feedback

3. **Removed green dot indicators**
   - Pulsing green dots removed from matching format cards
   - Border highlighting removed
   - "Show only matching" toggle makes indicators redundant
   - Kept subtle blue background for matching cards

4. **Simplified size filter panel**
   - Removed "Select all matching" button from panel
   - Cleaner layout with just chips and toggle
   - Counter still shows "X matching / Y total"

**Result:**
- Cleaner, less cluttered interface
- Simple select/deselect workflow
- "Show only matching" toggle provides clear filtering
- Better alignment with user expectations

Addresses user feedback in PR #690.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
bokelley and others added 7 commits November 4, 2025 06:56
Added inventoryCache object to store full metadata (sizes, ad_unit_ids) for
selected ad units and placements. This cache will power the new creative format
size filtering features:

- inventoryCache.adUnits: Maps ad unit IDs to full item data with sizes
- inventoryCache.placements: Maps placement IDs to full item data with ad_unit_ids
- inventoryCache.extractedSizes: Set of all unique sizes from selected inventory
- inventoryCache.sizeUnitCounts: Map of size -> count of units with that size

Part of creative format UX improvements to help users:
- See which sizes are available in selected inventory
- Filter formats by matching sizes
- Quick-select all matching formats

Related to product expert recommendation for progressive disclosure UX.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
…ions

Implements comprehensive size-based filtering system for creative formats:

**UI Enhancements:**
- Added size chips panel showing dimensions extracted from selected inventory
- Size chips display count of ad units/placements with each size
- Visual match indicators (green dot + highlight) on matching format cards
- "Select all matching" button for quick format selection
- "Show only matching" toggle to filter format display
- Toast notifications for user feedback

**Data Flow:**
- Extracts sizes from selected ad units directly via metadata
- For placements, looks up their ad_unit_ids and fetches associated sizes
- Caches all inventory items with metadata for performance
- Real-time updates as user modifies inventory selection

**Visual Design:**
- Blue size chips with hover effects (sorted by frequency)
- Green match indicators with pulse animation
- Inline size display for selected ad units
- Ad unit count display for selected placements

**Progressive Disclosure:**
- Size filter panel hidden until inventory selected
- "Select all matching" button appears when matches found
- Handles 1×1 native formats appropriately
- Format name parsing supports various dimension formats

Addresses product expert recommendations for intuitive format selection
based on inventory characteristics.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Enhances the inventory picker modal to display the number of ad units
associated with each placement, similar to how ad unit sizes are shown.

**Changes:**
- Placements now show "X ad units" below the placement name
- Blue styling for ad unit count (vs green for ad unit sizes)
- Helps users understand placement scope before selection

**Visual Design:**
- Ad units: "Sizes: 300×250, 728×90" (green text)
- Placements: "5 ad units" (blue text)

Implements user feedback for better placement context in modal.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Fixes the "0 matching" issue where format cards weren't being matched
against inventory sizes.

**Root Cause:**
- Format matching was only looking at text content of format cards
- The actual dimensions are stored in the `data-dimensions` attribute
- This caused zero matches even when compatible formats existed

**Solution:**
- Updated `updateFormatMatchIndicators()` to read `data-dimensions` attribute
- Falls back to extracting from text content if needed
- Now properly identifies matching formats

**Workflow Fix:**
- Moved `updateMatchingFormatsCount()` call into `updateFormatMatchIndicators()`
- Ensures count updates after match indicators are added
- Removed duplicate call from `updateSizeChipsPanel()`

**Result:**
- Format cards now properly show green dots when they match inventory sizes
- "X matching / 38 total formats" counter works correctly
- "Select all matching" button appears when matches exist

Fixes GitHub issue reported in PR #690.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Removes confusing "Map to Selected Inventory" button and green dot
indicators in favor of a cleaner, simpler interface.

**Changes:**

1. **Removed "Map to Selected Inventory" button**
   - Was confusing being far from the inventory section
   - Auto-mapping logic removed

2. **Added simple Select/Deselect All buttons**
   - "✓ Select All" - selects all visible formats
   - "✗ Deselect All" - deselects all formats
   - Works with "Show only matching" filter (only selects visible)
   - Shows toast notifications for feedback

3. **Removed green dot indicators**
   - Pulsing green dots removed from matching format cards
   - Border highlighting removed
   - "Show only matching" toggle makes indicators redundant
   - Kept subtle blue background for matching cards

4. **Simplified size filter panel**
   - Removed "Select all matching" button from panel
   - Cleaner layout with just chips and toggle
   - Counter still shows "X matching / Y total"

**Result:**
- Cleaner, less cluttered interface
- Simple select/deselect workflow
- "Show only matching" toggle provides clear filtering
- Better alignment with user expectations

Addresses user feedback in PR #690.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Fixes JavaScript errors preventing the inventory picker modal from closing
when clicking "Apply Selection".

**Problem:**
- Modal wouldn't close after selecting placements
- Console errors: "TypeError: null is not an object (evaluating 'button.style')"
- `updateAutoMapButton()` was trying to access removed UI elements

**Root Cause:**
- "Map to Selected Inventory" button and related functions were removed in
  previous commit (UI simplification)
- Two function calls to `updateAutoMapButton()` remained
- Function definition for `updateAutoMapButton()` and
  `autoMapFormatsToInventory()` still existed

**Solution:**
- Removed `updateAutoMapButton()` call from `applyInventorySelection()`
- Removed `updateAutoMapButton()` call from DOMContentLoaded handler
- Deleted `updateAutoMapButton()` function definition (~15 lines)
- Deleted `autoMapFormatsToInventory()` function definition (~50 lines)

**Result:**
- Modal closes correctly after "Apply Selection"
- No JavaScript errors
- Cleaner codebase without dead code

Fixes issue reported with placement selection modal.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Fix critical format validation bug: remove /mcp from creative agent URL
- Add 'Select All Matching' button for inventory-based format selection
- Fix formats not displaying on edit page load with existing inventory
- Optimize async fetching: batch ad unit fetches instead of sequential
- Add error feedback with toast notifications
- Enhanced debug logging for format validation
- Address code review feedback: eliminate race conditions in async code

Co-authored-by: code-reviewer agent
@bokelley bokelley force-pushed the feature/creative-format-size-filtering branch from 66b578f to 273c6f5 Compare November 4, 2025 12:04
@bokelley bokelley merged commit ced6466 into main Nov 4, 2025
10 checks passed
danf-newton pushed a commit to Newton-Research-Inc/salesagent that referenced this pull request Nov 24, 2025
…ions (prebid#690)

* feat: add global inventory cache for creative format size filtering

Added inventoryCache object to store full metadata (sizes, ad_unit_ids) for
selected ad units and placements. This cache will power the new creative format
size filtering features:

- inventoryCache.adUnits: Maps ad unit IDs to full item data with sizes
- inventoryCache.placements: Maps placement IDs to full item data with ad_unit_ids
- inventoryCache.extractedSizes: Set of all unique sizes from selected inventory
- inventoryCache.sizeUnitCounts: Map of size -> count of units with that size

Part of creative format UX improvements to help users:
- See which sizes are available in selected inventory
- Filter formats by matching sizes
- Quick-select all matching formats

Related to product expert recommendation for progressive disclosure UX.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: add creative format size filtering with inventory-based suggestions

Implements comprehensive size-based filtering system for creative formats:

**UI Enhancements:**
- Added size chips panel showing dimensions extracted from selected inventory
- Size chips display count of ad units/placements with each size
- Visual match indicators (green dot + highlight) on matching format cards
- "Select all matching" button for quick format selection
- "Show only matching" toggle to filter format display
- Toast notifications for user feedback

**Data Flow:**
- Extracts sizes from selected ad units directly via metadata
- For placements, looks up their ad_unit_ids and fetches associated sizes
- Caches all inventory items with metadata for performance
- Real-time updates as user modifies inventory selection

**Visual Design:**
- Blue size chips with hover effects (sorted by frequency)
- Green match indicators with pulse animation
- Inline size display for selected ad units
- Ad unit count display for selected placements

**Progressive Disclosure:**
- Size filter panel hidden until inventory selected
- "Select all matching" button appears when matches found
- Handles 1×1 native formats appropriately
- Format name parsing supports various dimension formats

Addresses product expert recommendations for intuitive format selection
based on inventory characteristics.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: show ad unit count in placement picker modal

Enhances the inventory picker modal to display the number of ad units
associated with each placement, similar to how ad unit sizes are shown.

**Changes:**
- Placements now show "X ad units" below the placement name
- Blue styling for ad unit count (vs green for ad unit sizes)
- Helps users understand placement scope before selection

**Visual Design:**
- Ad units: "Sizes: 300×250, 728×90" (green text)
- Placements: "5 ad units" (blue text)

Implements user feedback for better placement context in modal.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: format matching now uses data-dimensions attribute

Fixes the "0 matching" issue where format cards weren't being matched
against inventory sizes.

**Root Cause:**
- Format matching was only looking at text content of format cards
- The actual dimensions are stored in the `data-dimensions` attribute
- This caused zero matches even when compatible formats existed

**Solution:**
- Updated `updateFormatMatchIndicators()` to read `data-dimensions` attribute
- Falls back to extracting from text content if needed
- Now properly identifies matching formats

**Workflow Fix:**
- Moved `updateMatchingFormatsCount()` call into `updateFormatMatchIndicators()`
- Ensures count updates after match indicators are added
- Removed duplicate call from `updateSizeChipsPanel()`

**Result:**
- Format cards now properly show green dots when they match inventory sizes
- "X matching / 38 total formats" counter works correctly
- "Select all matching" button appears when matches exist

Fixes GitHub issue reported in PR prebid#690.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: simplify format selection UX based on user feedback

Removes confusing "Map to Selected Inventory" button and green dot
indicators in favor of a cleaner, simpler interface.

**Changes:**

1. **Removed "Map to Selected Inventory" button**
   - Was confusing being far from the inventory section
   - Auto-mapping logic removed

2. **Added simple Select/Deselect All buttons**
   - "✓ Select All" - selects all visible formats
   - "✗ Deselect All" - deselects all formats
   - Works with "Show only matching" filter (only selects visible)
   - Shows toast notifications for feedback

3. **Removed green dot indicators**
   - Pulsing green dots removed from matching format cards
   - Border highlighting removed
   - "Show only matching" toggle makes indicators redundant
   - Kept subtle blue background for matching cards

4. **Simplified size filter panel**
   - Removed "Select all matching" button from panel
   - Cleaner layout with just chips and toggle
   - Counter still shows "X matching / Y total"

**Result:**
- Cleaner, less cluttered interface
- Simple select/deselect workflow
- "Show only matching" toggle provides clear filtering
- Better alignment with user expectations

Addresses user feedback in PR prebid#690.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: remove orphaned autoMapButton references causing modal errors

Fixes JavaScript errors preventing the inventory picker modal from closing
when clicking "Apply Selection".

**Problem:**
- Modal wouldn't close after selecting placements
- Console errors: "TypeError: null is not an object (evaluating 'button.style')"
- `updateAutoMapButton()` was trying to access removed UI elements

**Root Cause:**
- "Map to Selected Inventory" button and related functions were removed in
  previous commit (UI simplification)
- Two function calls to `updateAutoMapButton()` remained
- Function definition for `updateAutoMapButton()` and
  `autoMapFormatsToInventory()` still existed

**Solution:**
- Removed `updateAutoMapButton()` call from `applyInventorySelection()`
- Removed `updateAutoMapButton()` call from DOMContentLoaded handler
- Deleted `updateAutoMapButton()` function definition (~15 lines)
- Deleted `autoMapFormatsToInventory()` function definition (~50 lines)

**Result:**
- Modal closes correctly after "Apply Selection"
- No JavaScript errors
- Cleaner codebase without dead code

Fixes issue reported with placement selection modal.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: optimize format loading and add Select All Matching button

- Fix critical format validation bug: remove /mcp from creative agent URL
- Add 'Select All Matching' button for inventory-based format selection
- Fix formats not displaying on edit page load with existing inventory
- Optimize async fetching: batch ad unit fetches instead of sequential
- Add error feedback with toast notifications
- Enhanced debug logging for format validation
- Address code review feedback: eliminate race conditions in async code

Co-authored-by: code-reviewer agent

---------

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants