#3591838 Phase 3: Usage data + deletion
What's New: This adds a "Find instances" feature that shows where colors are used, and prevents you from deleting colors that are actively in use.
AI Disclosure: was used with the help of Kimi/Claude Sonnet, intentionally done in small batches so I was aware of what was being changed. The front-end changes should be pretty close to what I'd have done manually. There's a bit more magic on the PHP end.
Testing instructions
Setup
- Enable the test module
- Go to /admin/modules
- Enable Canvas Dev Mode
- Enable Canvas test code components color
- Click "Install"
- Run database updates if prompted
- Verify test data loaded
- You should now have 7 Brand Kit colors installed:
- Brand Red, Brand Green, Brand Blue (top level)
- 4 additional colors in two folders ("Pastel Lab Revelation" and "Absolute Neon Casserole")
Test 1: Find Instances - Unused Color Goal: Verify the "Find instances" feature shows no usage for an unused color.
- Go to Canvas root page
- Open Brand Kit panel (right sidebar)
- Hover over "Brand Green" color row
- Click the three-dot menu
- Click "Find instances" Expected:
✅ Popover opens showing color name and swatch✅ Shows "0 This color is not currently in use."✅ No pages or other entities listed
Test 2: Find Instances - Color in Use Goal: Verify usage data displays correctly when a color is used.
- Create a new Canvas page
- Add the "Three Colors" component from the Library panel
- In the component form, find the "brand - all" field
- Click the color picker trigger
- Select "Brand Red" from the Brand Kit colors list
- Publish the page
- Open Brand Kit panel
- Hover over "Brand Red", click three-dot menu
- Click "Find instances" Expected:
✅ Popover shows "1 instance / 1 page"✅ "Current pages" section visible✅ Your page title listed with a badge showing "1"✅ Component name "Three Colors" (or its label) shown✅ Arrow link next to component opens the editor with that component selected (in new tab)
Test 3: Delete Gate - Blocked by Current Page Goal: Prevent deletion of a color that's actively used. Setup: Continue from Test 2 (Brand Red is published on a page)
- Open Brand Kit panel
- Hover over "Brand Red", click three-dot menu
- Verify "Find instances" shows usage
- Click "Delete" from the menu Expected:
✅ Delete confirmation popover opens✅ Loading spinner appears briefly then disappears✅ Message says something like: "Brand Red is in use on 1 page or template. Remove all uses before deleting."✅ "Delete" button is disabled (grayed out, can't click)✅ Close the popover
Test 4: Delete Gate - Blocked by Pattern Goal: Prevent deletion when color is used in a saved Pattern. Setup: Continue from Test 3
- Open Layers panel
- Right-click on "Three Colors" component
- Select "Create pattern"
- Name it "Brand Red Pattern"
- Click "Add to library"
- Wait for pattern to save
- Open Brand Kit panel
- Hover over "Brand Red", click three-dot menu
- Click "Find instances" Expected:
✅ Shows "2 instances / 1 page" (component appears twice - once as instance, once in pattern)✅ "Configuration" section appears✅ "Brand Red Pattern" listed under Configuration
- Click "Delete" from menu Expected:
✅ Delete button still disabled✅ Message still says color is in use
Test 5: Delete Gate - Remove from Page, Still Blocked by Pattern Goal: Verify pattern usage alone still blocks deletion. Setup: Continue from Test 4
- In the component form, change "brand - all" field from "Brand Red" to "Brand Green"
- Publish the page
- Open Brand Kit panel
- Hover over "Brand Red", click three-dot menu
- Click "Find instances" Expected:
✅ Shows "1 instance" (only the pattern now)✅ No "Current pages" section✅ "Configuration" section shows "Brand Red Pattern"
- Click "Delete" Expected:
✅ Delete button still disabled✅ Message says color is in use
Test 6: Delete Gate - Prior Revision Warning Goal: Verify colors only in old revisions show a warning but allow deletion. Setup: Continue from Test 5 - need to remove Brand Red from the pattern
- Open Library panel
- Click "Patterns" tab
- Right-click "Brand Red Pattern"
- Click "Edit pattern"
- Click on the "Three Colors" component in the preview
- Change "brand - all" from "Brand Red" to "Brand Green"
- Publish
- Go back to your Canvas page (click "Pages" in header, then your page)
- Open Brand Kit panel
- Hover over "Brand Red", click three-dot menu
- Click "Find instances" Expected:
✅ Shows "0 instances found"✅ No current pages or configuration listed
- Click "Delete" Expected:
✅ Loading spinner appears briefly then disappears✅ Delete button is enabled (not grayed out)✅ Warning message mentions "past version" or "prior revision"✅ Message warns that reverting to old versions will break
- Close the popover (don't delete yet)
Test 7: Successful Deletion Goal: Actually delete a color that's only in old revisions. Setup: Continue from Test 6
- Hover over "Brand Red", click three-dot menu
- Verify "Find instances" still shows "0 instances found"
- Click "Delete"
- Verify delete button is enabled
- Click the "Delete" button Expected:
✅ "Brand Red" color row disappears from the Brand Kit✅ No error messages
Test 8: Delete Unused Color (Happy Path) Goal: Delete a color that's never been used.
- Open Brand Kit panel
- Hover over "Brand Blue" (assuming you haven't used it)
- Click three-dot menu
- Click "Find instances" Expected:
✅ Shows "0 instances found"
- Click "Delete" Expected:
✅ No warning about prior versions✅ Delete button immediately enabled✅ Standard confirmation message
- Click "Delete" Expected:
✅ Color deleted successfully✅ Color row disappears Edge Cases to Test Nested Components with Ancestor Labels
- Create a page with nested sections/containers
- Place a component with a color prop deep in the hierarchy
- Use a Brand Kit color
- Publish
- Find instances on that color Expected:
✅ Component shown grouped under its parent section✅ Ancestor path visible (e.g., "Hero Section" as section header) Multiple Uses in Same Page
- Add the "Three Colors" component twice on same page
- Use same Brand Kit color in both
- Publish
- Find instances Expected:
✅ Shows both components✅ Count accurate
Existing Audit Issues
ConfigAuditBase is ComponentAudit from 1.x with the component-specific parts moved into subclasses. These behaviors existed on 1.x and are unchanged here; they now affect ColorAudit too. Follow-ups, not fixed in this MR:
getContentRevisionsUsingAuditTarget()loads every matching revision withloadMultipleRevisions(), no limit. WithRevisionAuditEnum::Allthat is the full revision history of every matching entity.componentDetails()paginates after loading;colorDetails()does not paginate. Tracked in #3522953.- Translated config (language config overrides of a
Pattern,ContentTemplateorPageRegioncomponent tree) is not audited (@todoinhasUsages(), https://www.drupal.org/i/3522198). Content entity translations are audited for colors as of this MR. - Field config and base field definition default values are not audited (
@todoinhasUsages()). getAutoSavesUsingAuditTarget()skips auto-saves of entities that do not implementComponentTreeEntityInterfacewith a deprecation (https://www.drupal.org/i/3520487).getConfigEntityUsageCount()has no static caching (https://www.drupal.org/i/3522953).- One entity query per content entity type per call;
ComponentListBuildertriggers this per row (https://www.drupal.org/i/3522953).
Closes #3591838 (closed)
Edited by Ted Bowman