@if (strings().label?.cheatsheet?.subtitle) {
{{ strings().label?.cheatsheet?.subtitle }}
}
@if (strings().label?.cheatsheet?.footerHint) {
{{ strings().label?.cheatsheet?.footerHint }}
}
search
@for (g of visibleGroups(); track g.key) {
{{ g.name }}
@if (g.description) {
{{ g.description }}
}
@for (p of filteredPrompts(g.prompts); track p) {
}
}
@if (emptyResults()) {
{{ strings().label?.cheatsheet?.empty }}
}
`,
styles: [`
/* mat-dialog-content must be zero-padded so the sticky block can reach
the true top of the scroll container (no 24px MDC default padding). */
.p3xr-cheatsheet-content.mat-mdc-dialog-content {
padding: 0 !important;
}
.p3xr-cheatsheet-sticky {
position: sticky;
top: 0;
z-index: 2;
background: var(--mat-app-background-color, inherit);
border-bottom: 1px solid var(--p3xr-content-border-color, rgba(255, 255, 255, 0.08));
padding: 12px 16px;
}
.p3xr-cheatsheet-sub,
.p3xr-cheatsheet-tip {
font-size: 13px;
opacity: 0.8;
line-height: 1.4;
padding-bottom: 4px;
}
.p3xr-cheatsheet-search {
margin: 0;
padding: 4px 0 0 0;
}
/* Kill every source of extra vertical space mat-form-field adds around
the input so the sticky block's padding is the ONLY vertical spacing. */
.p3xr-cheatsheet-search .mat-mdc-form-field-subscript-wrapper,
.p3xr-cheatsheet-search .mat-mdc-form-field-bottom-align {
display: none !important;
height: 0 !important;
min-height: 0 !important;
}
.p3xr-cheatsheet-search .mat-mdc-text-field-wrapper,
.p3xr-cheatsheet-search .mat-mdc-form-field {
margin: 0 !important;
}
.p3xr-cheatsheet-groups {
padding: 12px 16px;
}
.p3xr-cheatsheet-group:first-child .p3xr-cheatsheet-group-name {
margin-top: 0;
}
/* Only mat-dialog-content scrolls — this block is inline so the dialog owns the single scrollbar. */
.p3xr-cheatsheet-groups {
padding: 0 16px 16px 16px;
}
.p3xr-cheatsheet-group {
margin-bottom: 18px;
}
.p3xr-cheatsheet-group-name {
font-size: 14px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.5px;
margin-top: 6px;
margin-bottom: 4px;
opacity: 0.85;
}
.p3xr-cheatsheet-group-desc {
font-size: 12px;
opacity: 0.65;
margin-bottom: 8px;
}
.p3xr-cheatsheet-prompts {
display: flex;
flex-direction: column;
gap: 4px;
}
/* Plain bordered button — avoids mat-stroked-button's absolutely-positioned
border element that doesn't wrap with multi-line content. Consistent padding
on both single- and multi-line prompts. */
.p3xr-cheatsheet-prompt {
display: block;
width: 100%;
text-align: left;
font-family: 'Roboto Mono', monospace;
font-size: 12px;
line-height: 1.5;
padding: 8px 12px;
border: 1px solid var(--p3xr-content-border-color, rgba(127, 127, 127, 0.3));
border-radius: 4px;
background: transparent;
color: inherit;
cursor: pointer;
white-space: normal;
word-break: break-word;
overflow-wrap: anywhere;
transition: background 0.1s ease, border-color 0.1s ease;
}
.p3xr-cheatsheet-prompt:hover {
background: var(--p3xr-accordion-bg, rgba(127, 127, 127, 0.12));
border-color: var(--mat-sys-primary, currentColor);
}
.p3xr-cheatsheet-prompt:focus-visible {
outline: 2px solid var(--mat-sys-primary, currentColor);
outline-offset: -1px;
}
.p3xr-cheatsheet-empty {
padding: 24px;
text-align: center;
opacity: 0.6;
font-size: 13px;
}
.p3xr-cheatsheet-footer {
padding: 10px 16px !important;
min-height: auto !important;
}
.p3xr-cheatsheet-footer-hint {
font-size: 11px;
opacity: 0.7;
line-height: 1.4;
}
`],
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AiCheatsheetDialogComponent {
readonly strings;
filter = '';
constructor(
@Inject(I18nService) private readonly i18n: I18nService,
@Inject(RedisStateService) private readonly state: RedisStateService,
@Inject(ChangeDetectorRef) readonly cdr: ChangeDetectorRef,
@Inject(MatDialogRef) private readonly dialogRef: MatDialogRef