#87 - testing-fab#88
Conversation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adds project terminology definitions for the planned “Testing FAB” feature so Consumer applications and the Library share consistent language when documenting/implementing the FAB and its widgets.
Changes:
- Introduces standardized terms: Testing FAB, Action Widget, Select Query Param Widget, Custom Component Widget.
- Documents behavioral concepts (URL-authoritative selection, opt-in provisioning, Consumer-owned activation safety).
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
mumenthalers
left a comment
There was a problem hiding this comment.
@copilot fix comments. make use of the mcp to get info
| import { TESTING_FAB_WIDGETS } from './testing-fab-config.token' | ||
| import { TestingFabWidget } from './testing-fab-widget.type' | ||
|
|
||
| export function provideTestingFab(widgets: readonly TestingFabWidget[]): EnvironmentProviders { |
There was a problem hiding this comment.
it should accept a static config OR one that can be a provider itself (ValueOrFactory as in withCloudWatchLogV2Transport)
| export interface TestingFabCustomComponentWidget extends TestingFabWidgetBase { | ||
| type: 'custom-component' | ||
| component: Type<unknown> | ||
| inputs?: Record<string, unknown> |
There was a problem hiding this comment.
skip inputs just the component
| <section *ngIf="isOpen()" class="sc-testing-fab__panel"> | ||
| <ng-container *ngFor="let widget of widgets; trackBy: trackById"> |
There was a problem hiding this comment.
use new angular control flow @if and @for and so on. no more using the directives
| 🧪 | ||
| </button> | ||
|
|
||
| <section *ngIf="isOpen()" class="sc-testing-fab__panel"> |
There was a problem hiding this comment.
use a native popover (ask mdn) with nice css only animations and toggle action triggered without JS
| protected runAction(widget: TestingFabActionWidget) { | ||
| widget.action() | ||
| } |
There was a problem hiding this comment.
call directly .action instead of wrapping it here in an extra func
| protected setQueryParam(widget: TestingFabSelectQueryParamWidget, event: Event) { | ||
| const nextValue = (event.target as HTMLSelectElement).value | ||
| void this.router.navigate([], { | ||
| queryParams: { | ||
| [widget.queryParam]: nextValue || null, | ||
| }, | ||
| queryParamsHandling: 'merge', | ||
| }) | ||
| } |
There was a problem hiding this comment.
most cases i can think of will require a hard reload afterwards. add it as option (whether it's needed). when it is, do the reload direxctly to the url with the param withou using angular first
| }) | ||
| } | ||
|
|
||
| protected trackById(_index: number, widget: TestingFabWidget): string { |
There was a problem hiding this comment.
mthod unused when sing modern control flow
| protected asActionWidget(widget: TestingFabWidget): TestingFabActionWidget | null { | ||
| return widget.type === 'action' ? widget : null | ||
| } | ||
|
|
||
| protected asSelectWidget(widget: TestingFabWidget): TestingFabSelectQueryParamWidget | null { | ||
| return widget.type === 'select-query-param' ? widget : null | ||
| } | ||
|
|
||
| protected asCustomComponentWidget(widget: TestingFabWidget): TestingFabCustomComponentWidget | null { | ||
| return widget.type === 'custom-component' ? widget : null | ||
| } |
There was a problem hiding this comment.
angalr select control flow can do proper type narrowing when sing the modern @switch
| import { TestingFabWidget } from './testing-fab-widget.type' | ||
|
|
||
| export function provideTestingFab(widgets: readonly TestingFabWidget[]): EnvironmentProviders { | ||
| return makeEnvironmentProviders([{ provide: TESTING_FAB_WIDGETS, useValue: widgets }]) |
There was a problem hiding this comment.
how will the component be rendered?
do it like this:
| return makeEnvironmentProviders([{ provide: TESTING_FAB_WIDGETS, useValue: widgets }]) | |
| return makeEnvironmentProviders([ | |
| { provide: TESTING_FAB_WIDGETS, useValue: widgets }, | |
| provideEnvironmentInitializer(() => initializerTestingFab()) | |
| ]) |
where initializerTestingFab looks like
export function initializeDataSourceSwitcher() {
const doc = inject(DOCUMENT)
const appRef = inject(ApplicationRef)
const envInjector = inject(EnvironmentInjector)
const host = doc.createElement('sc-testing-fab')
const cmpRef = createComponent(TestingFabComponent, {
hostElement: host,
environmentInjector: envInjector,
})
appRef.attachView(cmpRef.hostView)
doc.body.appendChild(host)
}
Addressed in commit I updated the Testing FAB provider API and rendering initializer, migrated the component to modern Angular control flow + native popover, added hard-reload support for select query-param widgets, removed custom-component |
|
@copilot fix fox |
Fixed in commit |
|
@copilot fix formatting (prettier). also make sure lint, test, build will run |
Addressed in commit I applied Prettier formatting fixes to the 4 failing Testing FAB files. I also checked Actions via MCP: the new workflow run for this commit is |
|
@copilot now linting failed. you know that you can execute those commands yourself? and when commitin it should actually be run by husky, right? |
Fixed in commit I checked the failing CI lint job via MCP logs, reproduced the issue context locally as far as this sandbox allows, and fixed the reported lint violations in the Testing FAB files. And yes: commits should run Husky pre-commit here ( |
Implements a configurable Testing FAB in
@shiftcode/ngx-componentsinstead of only documenting terminology.Changes Made
TestingFabComponentas a floating, always-on-top FAB with an expandable control panel.provideTestingFab(...)for opt-in provisioning.libs/components/src/public-api.ts.URL,HTML) inCONTEXT.md.provideTestingFab(...)to accept either a static widget config or a factory (ValueOrFactorypattern).sc-testing-fabautomatically viacreateComponent(...)andprovideEnvironmentInitializer(...).inputssupport).hardReloadsupport for select-query-param widgets to optionally update the URL and reload directly.@for,@switch,@let) and switched toggle behavior to nativepopover.inset,margin,size,border-radius, background/foreground colors, and icon URL with default Shiftcode logo).