Skip to content

Refactor shared assets filter into reusable DotFilterBar components - #37374

Open
nicobytes wants to merge 11 commits into
mainfrom
nicobytes/37174-improvements-to-the-shared-content-drive-components-folder-tree-filter-chips-row-selection-and-scoped-upload
Open

Refactor shared assets filter into reusable DotFilterBar components#37374
nicobytes wants to merge 11 commits into
mainfrom
nicobytes/37174-improvements-to-the-shared-content-drive-components-folder-tree-filter-chips-row-selection-and-scoped-upload

Conversation

@nicobytes

@nicobytes nicobytes commented Sep 3, 2026

Copy link
Copy Markdown
Member

This pull request refactors how the "shared assets" filter is implemented and shared between the Content Drive and AssetPicker features. The filter logic and UI component are now centralized in @dotcms/ui, ensuring consistent behavior and removing duplicated code. The changes also introduce a store-agnostic facade for filter operations, making the filter chips reusable across different parts of the application. Additionally, the PR updates tests and documentation to reflect these architectural improvements.

Shared Assets Filter Refactor and Reuse

  • The dot-content-drive-shared-assets-filter component is removed from the Content Drive and replaced with the new, shared dot-shared-assets-filter component from @dotcms/ui, allowing the same filter UI and logic to be used in both Content Drive and AssetPicker. [1] [2] [3] [4]

  • The constants for the shared assets filter (SHARED_ASSETS_FILTER_KEY, SHARED_ASSETS_ENABLED_VALUE, SHARED_ASSETS_DISABLED_VALUE) are now re-exported from @dotcms/ui instead of being defined locally, ensuring a single source of truth for these values.

Store Facade Introduction and Integration

  • A new provideContentDriveFilterFacade provider is introduced and registered alongside the Content Drive store. This facade abstracts filter operations so that filter chips interact with a store-agnostic interface, supporting reuse and encapsulation. [1] [2] [3] [4] [5]

  • The toolbar and shell component tests are updated to provide the filter facade, ensuring that components using the shared filter chips have access to the correct store instance. [1] [2] [3] [4]

Testing and Conformance

  • A new test suite (content-drive-filter-facade.spec.ts) is added to verify that the Content Drive's filter facade conforms to the shared filter chip interface and encoding expectations, ensuring consistent filter behavior and encoding/decoding logic across surfaces.

Documentation

  • The migration guide is updated to clarify the behavior of the status filter, especially how the "live" option affects the status filter UI in the dialog.

This PR fixes: #37174

- Extracts the shared-assets toggle chip and a new DotFilterFacade
  seam into `@dotcms/ui` so both Content Drive and the AssetPicker
  drive it through the same store-agnostic contract instead of each
  surface reimplementing it.
- Adds facade implementations for both stores plus a shared
  conformance test suite so their differing encodings (numeric vs.
  named base types) can't silently drift apart.
- Fixes AssetPicker defects surfaced along the way: clearFilters
  used to drop the caller-seeded locale/base types, the filter bag
  couldn't hold dynamic/new keys, and includeSystemHost was hardcoded
  true with no way to turn it off.
- Introduces DotFilterBarComponent (layout + clear-all) plus content-type,
  language, and status filter chip adapters that bind the shared facade to
  presentational filters, so both surfaces gain the same chip set without
  duplicating adapter logic.
- Adds a DOT_RELATIONSHIP_PICKER token so the field filter can offer a
  Relationship picker where a surface supplies it, avoiding a circular
  dependency on @dotcms/edit-content.
- Updates spec.md with the resolved decision and new FRs (FR-020/FR-021,
  SC-010) covering optional per-surface filter extensions.
…ontent-drive-components-folder-tree-filter-chips-row-selection-and-scoped-upload
@github-actions github-actions Bot added the Area : Frontend PR changes Angular/TypeScript frontend code label Sep 3, 2026
@claude

claude Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Claude finished @nicobytes's task in 1m 59s —— View job


Code Review — PR #37374

Reviewed the facade seam, the shared chips, and the Content Drive toolbar wiring against origin/main. Good news first: several of the earlier review findings are already fixed on the current head.

New Issues

  • 🟠 High: core-web/libs/ui/src/lib/components/dot-filter-bar/chips/dot-language-filter-chip/dot-language-filter-chip.component.ts:16-19Content Drive's language chip lost its "non-removable when only the default is selected" behavior. DotLanguageFilterComponent.$removable defaults to true (dot-language-filter.component.ts:78) and this adapter never binds [removable]. The deleted dot-content-drive-language-field.component.ts computed removable = false when the sole selection was defaultLanguageId(). Result on Content Drive: the X always shows, and clicking it calls removeFilter('languageId'), which withFilterDefaults immediately re-seeds to the same default while resetting paging — a visible control whose only effect is sending the user back to page 1. The $removable JSDoc still documents exactly this case. The five describe('removable') tests were deleted with no replacement. Either thread the default-language id into the chip (input or facade) and bind [removable], or drop the removable input from the presentational component. Fix this →

  • 🟡 Medium: core-web/libs/portlets/dot-content-drive/portlet/src/lib/components/dot-content-drive-toolbar/dot-content-drive-toolbar.component.html:76-124The action-execution indicator will wrap to its own row. The container is flex w-full flex-wrap, and <dot-filter-bar> now carries host: { class: 'block w-full' } (dot-filter-bar.component.ts:30). Since the bar is a full-width flex item, its ml-auto sibling gets pushed onto a new line instead of right-aligning on the filter row — contradicting the "Sits at the end of the filter row" comment. Worth a screenshot with a bulk action running; likely the bar and the indicator need to share a flex context (e.g. bar not w-full, or the indicator moved inside the bar).

  • 🟡 Medium: dot-content-type-filter-chip.component.ts:26-32 and dot-language-filter-chip.component.ts:16-20 — Both still use inline template: strings. @zJaaal requested these be extracted to .html files (consistent with every sibling chip: dot-shared-assets-filter, dot-status-filter, dot-field-filter all use templateUrl). Convention, non-blocking, but it's an open change request.

  • 🟡 Medium: content-drive-filter-facade.ts:17, asset-picker-filter-facade.ts:14, filter-defaults.ts:73sameValue is duplicated three times. It implements the O9 "a no-op patch must not notify or reset paging" guard — the one thing the contract flags as easy to get wrong — so a single exported helper next to toFilterValues in filter-facade.token.ts would keep the three surfaces from drifting.

Resolved (from earlier reviews)

  • content-drive-filter-facade.ts:33-41toBaseTypeNames now returns undefined for an absent key (was []), satisfying the O2 "unset ≠ empty selection" contract. Copilot's finding is addressed.
  • dot-content-type-filter-chip.component.ts:50-56 and dot-language-filter-chip.component.ts:27-29 — the unsafe as string[] casts are gone; both now normalize through toFilterValues(), so a single stored string no longer risks a .map() TypeError. Copilot's findings addressed (and the language chip has an explicit "single stored string" test).
  • dot-filter-bar.component.tsDotFilterBarComponent is now wired into dot-content-drive-toolbar.component.html:80, so it's no longer dead surface area.

Notes (not blocking)

  • dot-status-filter.component.ts:134-148 — the bounding effect returns before reading $selection() on the !allowed branch, so $selection isn't a dependency there. Harmless as written, but reading both signals up front is the safer habit.
  • The behavior-change questions @zJaaal raised (every non-browse picker now offering an Archived filter; showFolders diverging between the two surfaces; status: 'archived' resting on backend defaulting with only negative assertions) are worth confirming against a running instance and/or a spec line — I can't verify those from the diff alone.
  • Per the repo spec-kit commit policy (root CLAUDE.md), only spec.md and contracts/ should land; specs/37174-shared-picker-toolbar/data-model.md is committed and should be dropped.

The type-safety and contract regressions the earlier bots caught are genuinely fixed. The language-chip removable regression is the one I'd treat as blocking, since it ships a control that does nothing but reset pagination.

Review by Claude (Opus 4.8).

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The Content Drive facade currently violates the facade “unset == undefined” contract for baseType, and a couple of shared chips make unsafe string[] casts that can throw if a surface ever stores/restores a single-string filter value.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR centralizes the “Shared Assets” filter and related filter-chip plumbing so both Content Drive and the Asset Picker can share the same chip UI while talking to their own stores through a store-agnostic DotFilterFacade seam. It also introduces a reusable conformance test suite to keep both surfaces’ filter behaviors aligned over time.

Changes:

  • Added DOT_FILTER_FACADE contract + per-surface facades (Content Drive + Asset Picker) and a shared conformance suite exported via @dotcms/ui/testing.
  • Moved the Shared Assets chip into @dotcms/ui and wired the Asset Picker request to honor includeSystemHost based on the chip state.
  • Updated store models/defaults and expanded test coverage for filter defaults, “Clear all” semantics, and shared-assets behavior.
File summaries
File Description
specs/37174-shared-picker-toolbar/spec.md Feature spec for shared picker toolbar work (scope: finding 6).
specs/37174-shared-picker-toolbar/data-model.md Data model and invariants for facade, normalized values, and defaults.
specs/37174-shared-picker-toolbar/contracts/filter-facade.contract.md Formal contract/obligations for DOT_FILTER_FACADE and shared conformance suite.
core-web/tsconfig.base.json Adds TS path alias for @dotcms/ui/testing.
core-web/libs/ui/tsconfig.lib.json Excludes test-only entrypoints from production compilation.
core-web/libs/ui/src/testing.ts Test-only barrel exporting the conformance suite.
core-web/libs/ui/src/lib/components/dot-filter-bar/testing/filter-facade.conformance.ts Shared Jest suite asserting facade obligations O1–O9.
core-web/libs/ui/src/lib/components/dot-filter-bar/filter-facade.token.ts Defines DotFilterFacade, DotFilterValue, and the injection token.
core-web/libs/ui/src/lib/components/dot-filter-bar/dot-filter-bar.component.ts Introduces shared filter-bar wrapper component (projection + Clear all).
core-web/libs/ui/src/lib/components/dot-filter-bar/dot-filter-bar.component.spec.ts Unit tests for projection behavior, Clear all visibility, and wrapping layout.
core-web/libs/ui/src/lib/components/dot-filter-bar/dot-filter-bar.component.html Template for projected chips plus conditional Clear all button.
core-web/libs/ui/src/lib/components/dot-filter-bar/constants.ts Canonical chip order + helper to validate subsequence ordering.
core-web/libs/ui/src/lib/components/dot-filter-bar/chips/dot-status-filter/dot-status-filter.component.ts New shared Status chip implementation wired via DOT_FILTER_FACADE.
core-web/libs/ui/src/lib/components/dot-filter-bar/chips/dot-status-filter/dot-status-filter.component.spec.ts Status chip tests incl. allowed-options bounding behavior.
core-web/libs/ui/src/lib/components/dot-filter-bar/chips/dot-status-filter/dot-status-filter.component.html Status chip UI (popover + listbox + bounded-note).
core-web/libs/ui/src/lib/components/dot-filter-bar/chips/dot-status-filter/constants.ts Shared constants for status filter key and options.
core-web/libs/ui/src/lib/components/dot-filter-bar/chips/dot-shared-assets-filter/dot-shared-assets-filter.component.ts Shared “Show Shared Assets” chip implementation via facade.
core-web/libs/ui/src/lib/components/dot-filter-bar/chips/dot-shared-assets-filter/dot-shared-assets-filter.component.spec.ts Updated tests to validate facade usage and canonical chip id attribute.
core-web/libs/ui/src/lib/components/dot-filter-bar/chips/dot-shared-assets-filter/dot-shared-assets-filter.component.html Shared-assets chip template.
core-web/libs/ui/src/lib/components/dot-filter-bar/chips/dot-shared-assets-filter/constants.ts Single-source-of-truth constants for shared-assets filter key/values.
core-web/libs/ui/src/lib/components/dot-filter-bar/chips/dot-language-filter-chip/dot-language-filter-chip.component.ts New adapter chip wiring dot-language-filter through the facade.
core-web/libs/ui/src/lib/components/dot-filter-bar/chips/dot-language-filter-chip/dot-language-filter-chip.component.spec.ts Unit tests for language chip facade binding and removal behavior.
core-web/libs/ui/src/lib/components/dot-filter-bar/chips/dot-field-filter/relationship-picker.token.ts Optional capability token for relationship-picker integration without circular deps.
core-web/libs/ui/src/lib/components/dot-filter-bar/chips/dot-content-type-filter-chip/dot-content-type-filter-chip.component.ts New adapter chip wiring content-type filter through the facade.
core-web/libs/ui/src/lib/components/dot-filter-bar/chips/dot-content-type-filter-chip/dot-content-type-filter-chip.component.spec.ts Unit tests for content-type chip facade binding + allowed-base-type bounds.
core-web/libs/ui/src/lib/components/dot-asset-picker/store/models.ts Expands picker filter model to support shared keys + dynamic field filters.
core-web/libs/ui/src/lib/components/dot-asset-picker/store/filter-defaults.ts Centralizes picker filter defaults + non-default detection.
core-web/libs/ui/src/lib/components/dot-asset-picker/store/features/with-asset-browse.feature.ts Drives includeSystemHost from shared-assets filter state.
core-web/libs/ui/src/lib/components/dot-asset-picker/store/dot-asset-picker.store.ts Adds $hasNonDefaultFilters, getFilterValue, and clears back to caller seeds.
core-web/libs/ui/src/lib/components/dot-asset-picker/store/dot-asset-picker.store.spec.ts Updates + adds tests for defaults restore, bag widening, and shared-assets behavior.
core-web/libs/ui/src/lib/components/dot-asset-picker/store/asset-picker-filter-facade.ts Adds picker facade + provider and idempotence guard.
core-web/libs/ui/src/lib/components/dot-asset-picker/store/asset-picker-filter-facade.spec.ts Runs shared conformance suite against Asset Picker implementation.
core-web/libs/ui/src/lib/components/dot-asset-picker/dot-asset-picker.component.ts Provides asset-picker facade alongside its store.
core-web/libs/ui/src/lib/components/dot-asset-picker/components/dot-asset-picker-toolbar/dot-asset-picker-toolbar.component.ts Renders shared-assets chip in the picker toolbar.
core-web/libs/ui/src/lib/components/dot-asset-picker/components/dot-asset-picker-toolbar/dot-asset-picker-toolbar.component.spec.ts Adds canonical-order tests and shared-assets rendering assertions.
core-web/libs/ui/src/lib/components/dot-asset-picker/components/dot-asset-picker-toolbar/dot-asset-picker-toolbar.component.html Adds <dot-shared-assets-filter /> to picker toolbar markup.
core-web/libs/ui/src/index.ts Re-exports shared filter constants/token and shared-assets chip from @dotcms/ui.
core-web/libs/portlets/dot-content-drive/portlet/src/lib/store/content-drive-filter-facade.ts Adds Content Drive facade (incl. base-type name↔number normalization).
core-web/libs/portlets/dot-content-drive/portlet/src/lib/store/content-drive-filter-facade.spec.ts Runs conformance suite against Content Drive implementation.
core-web/libs/portlets/dot-content-drive/portlet/src/lib/shared/constants.ts Re-exports shared-assets constants from @dotcms/ui.
core-web/libs/portlets/dot-content-drive/portlet/src/lib/dot-content-drive-shell/dot-content-drive-shell.component.ts Provides Content Drive facade alongside the store.
core-web/libs/portlets/dot-content-drive/portlet/src/lib/dot-content-drive-shell/dot-content-drive-shell.component.spec.ts Updates tests to include facade provider.
core-web/libs/portlets/dot-content-drive/portlet/src/lib/components/dot-content-drive-toolbar/dot-content-drive-toolbar.component.ts Replaces Content Drive-only shared-assets chip with shared @dotcms/ui chip.
core-web/libs/portlets/dot-content-drive/portlet/src/lib/components/dot-content-drive-toolbar/dot-content-drive-toolbar.component.spec.ts Adds facade provider for shared chip dependency graph.
core-web/libs/portlets/dot-content-drive/portlet/src/lib/components/dot-content-drive-toolbar/dot-content-drive-toolbar.component.html Switches <dot-content-drive-shared-assets-filter> to <dot-shared-assets-filter>.
core-web/libs/portlets/dot-content-drive/portlet/src/lib/components/dot-content-drive-toolbar/components/dot-content-drive-shared-assets-filter/dot-content-drive-shared-assets-filter.component.ts Removes Content Drive-only shared-assets component.
.claude/skills/dot-ui-vtl-migration/references/migration-guide.md Updates migration docs for status behavior (esp. "archived" semantics + "live" bounding).
Review details

Suppressed comments (1)

core-web/libs/ui/src/lib/components/dot-filter-bar/chips/dot-content-type-filter-chip/dot-content-type-filter-chip.component.ts:56

  • getFilterValue('contentType') may return string as well as string[]. The direct cast to string[] can throw if a single string is ever stored/restored. Normalize to an array (or []) before passing it to the presentational filter.
    protected readonly $contentTypes = computed(
        () => (this.#filters.getFilterValue('contentType') as string[]) ?? []
    );
  • Files reviewed: 46/47 changed files
  • Comments generated: 4
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Unblocks the `format-test` (nx format:check) step of PR Test / Frontend
Unit Tests, which was failing on these three files and preventing the
unit test and E2E jobs from running.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Content Drive's content-type, language, and status filters were bespoke
components duplicating what dot-filter-bar's chip adapters already do.
Route both toolbars through the shared bar/chips, move workflow and
field-filter chips onto the facade pattern, and fix the encoded-filter
undefined-vs-empty-array distinction that the base-type/language chips
were silently collapsing.
Content Drive's content-type, language, and status filters were bespoke
components duplicating what dot-filter-bar's chip adapters already do.
Route both toolbars through the shared bar/chips, move workflow and
field-filter chips onto the facade pattern, and fix the encoded-filter
undefined-vs-empty-array distinction that the base-type/language chips
were silently collapsing.
- Move field-filter/status-filter logic, single-selectable value casting, and the
  relationship-picker/error-reporting seams into `@dotcms/ui` behind host tokens so
  Content Drive and the Asset Picker consume one implementation instead of two.
- Replace the AssetPicker's `showArchived` pin with a shared, seedable Status chip
  (`status`), bounded to Locked-only when the picker is pinned to published content,
  so content condition has one representation across both surfaces.
- Re-export moved constants/utilities from their original locations to keep existing
  importers working, and update docs/spec/messages to reflect the shared chip pattern.
…e-components-folder-tree-filter-chips-row-selection-and-scoped-upload' of github.com:dotCMS/core into nicobytes/37174-improvements-to-the-shared-content-drive-components-folder-tree-filter-chips-row-selection-and-scoped-upload
@github-actions github-actions Bot added Area : Documentation PR changes documentation files and removed AI: Safe To Rollback labels Sep 4, 2026
- Introduced a new statusFilterFor function in AngularFormBridge to streamline status handling for asset picking, replacing the previous archived status logic with a more flexible approach.
- Updated DotContentDriveToolbarComponent tests to utilize the new DotContentDriveFilters type for improved type safety and clarity in filter management.
- Adjusted the getFilterValue method to return a DotFilterValue type, ensuring consistent typing across filter operations.
@zJaaal

zJaaal commented Sep 7, 2026

Copy link
Copy Markdown
Member

Review notes

Nice refactor. The three seams (DOT_FILTER_FACADE / DOT_FIELD_FILTER_HOST / DOT_RELATIONSHIP_PICKER) are the right shape, the conformance suite shared between both facades is a great idea, and I checked every moved us.* util body against main: they are faithful moves with only the parameter type widened, which takes a lot of risk off this diff. CI is green.

Findings below, roughly by severity. Numbers 1 and 2 I think are actual regressions; the rest are questions or gaps.

1. Content Drive's language chip lost its non-removable-by-default behavior

The old adapter passed [removable]="$removable()", computed as "false when the only selection is defaultLanguageId":

// dot-content-drive-language-field.component.ts (deleted)
protected readonly $removable = computed(() => {
    const selected = this.$selectedLanguageIds();
    return !(selected.length === 1 && selected[0] === this.#store.defaultLanguageId());
});

DotLanguageFilterChipComponent passes nothing, and DotLanguageFilterComponent.$removable defaults to true. So on Content Drive the X now always shows, and clicking it calls store.removeFilter('languageId'), which re-seeds the default through withFilterDefaults and resets paging: a visible control that does nothing except send you back to page 1. The removable input's own JSDoc still documents why Content Drive needs it ("removing that selection simply re-seeds the same value, so the X would do nothing visible").

The five tests covering this (describe('removable') in dot-content-drive-language-field.spec.ts) were deleted with no replacement.

2. The workflow-run indicator will likely wrap to its own row

DotFilterBarComponent has host: { class: 'block w-full' }. In dot-content-drive-toolbar.component.html the outer container is flex w-full flex-wrap, so <dot-filter-bar> is now a full-width flex item and the ml-auto action-execution indicator is its sibling rather than a sibling of the chips. It should get pushed onto a new line instead of right-aligning on the filter row. The comment above it still says "Sits at the end of the filter row." Worth a screenshot with a bulk action running.

3. status: 'archived' now depends on backend behavior nothing here asserts

archived is dropped from the picker request entirely and 'archived' becomes a seeded status: ['ARCHIVED']. That rests on POST /drive/search returning archived content for status: ['ARCHIVED'] with archived absent (defaulting false). Content Drive already ships this pattern so I expect it holds, but every assertion in this PR is negative (expect($request()).not.toHaveProperty('archived')), so nothing proves the positive. Could you confirm against a running instance?

4. Every picker now offers an Archived filter, not just browse mode

$allowedStatuses only bounds the chip when browse.showWorking === false, which only openBrowserModal({status:'live'}) sets. For a File or Image field browse is undefined, so all three conditions are offered and an editor can filter to Archived and reference an archived asset. The old pinned archived: false made that impossible. Intended? If so it is worth a line in the spec, because it is a behavior change for the four non-browse entry points that FR-014 does not obviously cover.

5. showFolders diverges between the two surfaces

Content Drive hides folders whenever status or userSearchable is set, with a long comment explaining folders carry no status. The picker's is just:

const showFolders = Boolean(browse?.showFolders) && (bookmark?.hasMoreFolders ?? true);

So openBrowserModal({kinds: ['folder', ...]}) plus a Status selection lists folders next to status-filtered content. Same shared chip, two answers.

6. Coverage gaps in code that used to be covered

Not asking for tests everywhere, but a few of these were previously tested and are now not:

  • content-drive-relationship-picker.ts, content-drive-field-filter-host.ts and asset-picker-field-filter-host.ts have no specs. The relationship dialog's real wiring (header, footer template, !ref guard, cancel to []) moved out of the tested component into the untested provider; the field-filter spec now only exercises a token mock.
  • The field.listed to "Show In List" split moved into the untested host, and its test ("should populate the Show In List fields from the content type listed fields") is gone.
  • The status chip lost its whole describe('with the real store') block, which covered the riskiest thing in that component: the linkedSignal + signalMethod write-back not looping, and "should not reset pagination when an unrelated filter changes." It also lost "should select when the LABEL is clicked, not just the checkbox" (the pointer-events-none trick) and the aria-label assertion.
  • $relationshipUnavailable has no test, though it ships a new i18n key.

7. sameValue is duplicated three times

Identical in content-drive-filter-facade.ts, asset-picker-filter-facade.ts and filter-defaults.ts. It is the O9 guard, i.e. the one thing the contract calls out as easy to get wrong, so it would be better as one export next to toFilterValues in filter-facade.token.ts.

8. Smaller things

  • dot-status-filter.component.ts: the effect reads $allowedOptions() and returns before reading $selection(), so $selection is not a dependency on the null branch. Harmless as written, but the safer habit is to read both signals up front.
  • toLocalIsoString brings date-fns into @dotcms/ui, which means into the legacy Dojo custom-element bundle. Probably fine, just flagging the weight.
  • The shared chips all use content-drive.* i18n keys, including the bar's own content-drive.filters.clear-all. Reads a bit odd now that the AssetPicker renders them.
  • specs/37174-shared-picker-toolbar/data-model.md is committed. Per our spec-kit commit policy it is spec.md always and contracts/ when there is a cross-team contract; data-model.md should not land.

Review by Claude Code (Opus 5), run and posted by @zJaaal.

[selectedBaseTypes]="$baseTypes()"
[selectedContentTypes]="$contentTypes()"
[allowedBaseTypes]="$allowedBaseTypes()"
(selectionChange)="onSelectionChange($event)" />

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should be using an html file

Comment on lines +17 to +21
<dot-language-filter
[selectedLanguageIds]="$languageIds()"
(selectionChange)="onSelectionChange($event)" />
`,
changeDetection: ChangeDetectionStrategy.OnPush,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need an html file

…ontent-drive-components-folder-tree-filter-chips-row-selection-and-scoped-upload
The generated header still reported 22 first-party skills after
speckit-docs-converge was added, so `skill-lint` failed the
"Lint skills" check with "CATALOG.md is stale".

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area : Documentation PR changes documentation files Area : Frontend PR changes Angular/TypeScript frontend code

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

Content Drive toolbar control, shared filter chips and row selection in the list view

3 participants