Warning, /firebird/packages/firebird-ng/display/src/lib/components/data-selector/presets-tab.component.ts is written in an unsupported language. File is not indexed.
0001 import { ChangeDetectionStrategy, Component, computed, inject, signal } from '@angular/core';
0002 import type { DataCatalogEntry } from '@dexvis/firebird-core';
0003 import { ResourceSelectComponent } from '../resource-select/resource-select.component';
0004 import { DataCatalogService, DataSelectionService } from '@dexvis/firebird-ng/api';
0005
0006 /**
0007 * Presets tab: pick a catalog entry by name. The entry sets geometry and
0008 * events at once. The drop-down opens on the entry that matches what is
0009 * configured, when there is one.
0010 */
0011 @Component({
0012 selector: 'firebird-presets-tab',
0013 changeDetection: ChangeDetectionStrategy.OnPush,
0014 imports: [ResourceSelectComponent],
0015 template: `
0016 <div class="tab-block">
0017 <firebird-resource-select
0018 [options]="names()"
0019 [selected]="fieldSeed"
0020 label="Preset"
0021 (valueChange)="onNameChange($event)">
0022 </firebird-resource-select>
0023
0024 @if (selected(); as entry) {
0025 <div class="description">
0026 @if (entry.description) {
0027 <p>{{ entry.description }}</p>
0028 }
0029 @if (entry.link) {
0030 <a [href]="entry.link" target="_blank" rel="noopener">More about this dataset</a>
0031 }
0032 <dl class="sources">
0033 @if (entry.geometry) {
0034 <dt>Geometry</dt><dd [title]="entry.geometry">{{ entry.geometry }}</dd>
0035 }
0036 <dt>Events</dt><dd [title]="entry.events ?? ''">{{ entry.events || 'none' }}</dd>
0037 </dl>
0038 </div>
0039 }
0040 </div>
0041 `,
0042 styles: `
0043 @use './shared';
0044
0045 .tab-block {
0046 @include shared.tab-block;
0047 }
0048
0049 .description {
0050 @include shared.description;
0051
0052 p {
0053 margin: 0 0 6px;
0054 }
0055 }
0056
0057 .sources {
0058 display: grid;
0059 grid-template-columns: max-content 1fr;
0060 gap: 2px 10px;
0061 margin: 8px 0 0;
0062 font-size: 0.72rem;
0063
0064 dt {
0065 opacity: 0.7;
0066 }
0067
0068 dd {
0069 margin: 0;
0070 min-width: 0;
0071 overflow: hidden;
0072 text-overflow: ellipsis;
0073 white-space: nowrap;
0074 font-family: monospace;
0075 }
0076 }
0077 `,
0078 })
0079 export class PresetsTabComponent {
0080 private readonly catalog = inject(DataCatalogService);
0081 private readonly selection = inject(DataSelectionService);
0082
0083 readonly names = computed(() => this.catalog.entries().map(entry => entry.name));
0084 /** The entry matching the typed name (drives the description), or null while typing. */
0085 readonly selected = signal<DataCatalogEntry | null>(this.selection.activeEntry());
0086 /**
0087 * Text the field starts with. A constant, not a binding to `selected`: a
0088 * live binding would flip to '' on the first keystroke (no exact match yet)
0089 * and wipe what the user is typing.
0090 */
0091 readonly fieldSeed = this.selected()?.name ?? '';
0092
0093 onNameChange(name: string): void {
0094 const entry = this.catalog.entries().find(candidate => candidate.name === name) ?? null;
0095 this.selected.set(entry);
0096 if (entry) {
0097 this.selection.updateDraft(this.selection.selectionForEntry(entry));
0098 }
0099 }
0100 }